[java-atk-wrapper] Text: add support for get_text_before/after_offset



commit 1c8b9f9765d493931b910e0677b934aaf8ae0aa8
Author: Samuel Thibault <samuel thibault ens-lyon org>
Date:   Sun Jul 28 11:58:06 2019 +0200

    Text: add support for get_text_before/after_offset

 jni/src/jawtext.c                            | 146 +++++++++++++++++++++++----
 wrapper/org/GNOME/Accessibility/AtkText.java |  42 ++++++++
 2 files changed, 166 insertions(+), 22 deletions(-)
---
diff --git a/jni/src/jawtext.c b/jni/src/jawtext.c
index 4fab54e..9f03e12 100644
--- a/jni/src/jawtext.c
+++ b/jni/src/jawtext.c
@@ -34,6 +34,18 @@ static gchar* jaw_text_get_text_at_offset(AtkText *text,
                                           gint *start_offset,
                                           gint *end_offset);
 
+static gchar* jaw_text_get_text_before_offset(AtkText *text,
+                                              gint offset,
+                                              AtkTextBoundary boundary_type,
+                                              gint *start_offset,
+                                              gint *end_offset);
+
+static gchar* jaw_text_get_text_after_offset(AtkText *text,
+                                             gint offset,
+                                             AtkTextBoundary boundary_type,
+                                             gint *start_offset,
+                                             gint *end_offset);
+
 static gint jaw_text_get_caret_offset(AtkText *text);
 
 static void jaw_text_get_character_extents(AtkText *text,
@@ -87,10 +99,10 @@ jaw_text_interface_init (AtkTextIface *iface, gpointer data)
 {
   JAW_DEBUG_ALL("%p, %p", iface, data);
   iface->get_text = jaw_text_get_text;
-  // TODO: iface->get_text_after_offset
+  iface->get_text_after_offset = jaw_text_get_text_after_offset;
   iface->get_text_at_offset = jaw_text_get_text_at_offset;
   iface->get_character_at_offset = jaw_text_get_character_at_offset;
-  // TODO: iface->get_text_before_offset
+  iface->get_text_before_offset = jaw_text_get_text_before_offset;
   iface->get_caret_offset = jaw_text_get_caret_offset;
   // TODO: iface->get_run_attributes by iterating getCharacterAttribute or using getTextSequenceAt with 
ATTRIBUTE_RUN
   // TODO: iface->get_default_attributes
@@ -235,6 +247,36 @@ jaw_text_get_character_at_offset (AtkText *text, gint offset)
   return (gunichar)jcharacter;
 }
 
+static gchar *jaw_text_get_gtext_from_string_seq(JNIEnv *jniEnv,
+                                                 jobject jStrSeq,
+                                                 gint *start_offset,
+                                                 gint *end_offset)
+{
+  jclass classStringSeq = (*jniEnv)->FindClass(jniEnv,
+                                               "org/GNOME/Accessibility/AtkText$StringSequence");
+  jfieldID jfidStr = (*jniEnv)->GetFieldID(jniEnv,
+                                           classStringSeq,
+                                           "str",
+                                           "Ljava/lang/String;");
+  jfieldID jfidStart = (*jniEnv)->GetFieldID(jniEnv,
+                                             classStringSeq,
+                                             "start_offset",
+                                             "I");
+  jfieldID jfidEnd = (*jniEnv)->GetFieldID(jniEnv,
+                                           classStringSeq,
+                                           "end_offset",
+                                           "I");
+
+  jstring jStr = (*jniEnv)->GetObjectField(jniEnv, jStrSeq, jfidStr);
+  jint jStart = (*jniEnv)->GetIntField(jniEnv, jStrSeq, jfidStart);
+  jint jEnd = (*jniEnv)->GetIntField(jniEnv, jStrSeq, jfidEnd);
+
+  (*start_offset) = (gint)jStart;
+  (*end_offset) = (gint)jEnd;
+
+  return jaw_text_get_gtext_from_jstr(jniEnv, jStr);
+}
+
 static gchar*
 jaw_text_get_text_at_offset (AtkText *text,
                              gint offset,
@@ -273,29 +315,89 @@ jaw_text_get_text_at_offset (AtkText *text,
     return NULL;
   }
 
-  jclass classStringSeq = (*jniEnv)->FindClass(jniEnv,
-                                               "org/GNOME/Accessibility/AtkText$StringSequence");
-  jfieldID jfidStr = (*jniEnv)->GetFieldID(jniEnv,
-                                           classStringSeq,
-                                           "str",
-                                           "Ljava/lang/String;");
-  jfieldID jfidStart = (*jniEnv)->GetFieldID(jniEnv,
-                                             classStringSeq,
-                                             "start_offset",
-                                             "I");
-  jfieldID jfidEnd = (*jniEnv)->GetFieldID(jniEnv,
-                                           classStringSeq,
-                                           "end_offset",
-                                           "I");
+  return jaw_text_get_gtext_from_string_seq(jniEnv, jStrSeq, start_offset, end_offset);
+}
 
-  jstring jStr = (*jniEnv)->GetObjectField(jniEnv, jStrSeq, jfidStr);
-  jint jStart = (*jniEnv)->GetIntField(jniEnv, jStrSeq, jfidStart);
-  jint jEnd = (*jniEnv)->GetIntField(jniEnv, jStrSeq, jfidEnd);
+static gchar*
+jaw_text_get_text_before_offset (AtkText *text,
+                                 gint offset,
+                                 AtkTextBoundary boundary_type,
+                                 gint *start_offset, gint *end_offset)
+{
+  JAW_DEBUG_C("%p, %d, %d, %p, %p", text, offset, boundary_type, start_offset, end_offset);
+  JawObject *jaw_obj = JAW_OBJECT(text);
+  if (!jaw_obj) {
+    JAW_DEBUG_I("jaw_obj == NULL");
+    return NULL;
+  }
+  TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
+  JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    JAW_DEBUG_I("atk_text == NULL");
+    return NULL;
+  }
 
-  (*start_offset) = (gint)jStart;
-  (*end_offset) = (gint)jEnd;
+  jclass classAtkText = (*jniEnv)->FindClass(jniEnv,
+                                             "org/GNOME/Accessibility/AtkText");
+  jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
+                                          classAtkText,
+                                          "get_text_before_offset",
+                                          "(II)Lorg/GNOME/Accessibility/AtkText$StringSequence;");
+  jobject jStrSeq = (*jniEnv)->CallObjectMethod(jniEnv,
+                                                atk_text,
+                                                jmid,
+                                                (jint)offset,
+                                                (jint)boundary_type );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
-  return jaw_text_get_gtext_from_jstr(jniEnv, jStr);
+  if (jStrSeq == NULL)
+  {
+    return NULL;
+  }
+
+  return jaw_text_get_gtext_from_string_seq(jniEnv, jStrSeq, start_offset, end_offset);
+}
+
+static gchar*
+jaw_text_get_text_after_offset (AtkText *text,
+                                gint offset,
+                                AtkTextBoundary boundary_type,
+                                gint *start_offset, gint *end_offset)
+{
+  JAW_DEBUG_C("%p, %d, %d, %p, %p", text, offset, boundary_type, start_offset, end_offset);
+  JawObject *jaw_obj = JAW_OBJECT(text);
+  if (!jaw_obj) {
+    JAW_DEBUG_I("jaw_obj == NULL");
+    return NULL;
+  }
+  TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
+  JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    JAW_DEBUG_I("atk_text == NULL");
+    return NULL;
+  }
+
+  jclass classAtkText = (*jniEnv)->FindClass(jniEnv,
+                                             "org/GNOME/Accessibility/AtkText");
+  jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
+                                          classAtkText,
+                                          "get_text_after_offset",
+                                          "(II)Lorg/GNOME/Accessibility/AtkText$StringSequence;");
+  jobject jStrSeq = (*jniEnv)->CallObjectMethod(jniEnv,
+                                                atk_text,
+                                                jmid,
+                                                (jint)offset,
+                                                (jint)boundary_type );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
+
+  if (jStrSeq == NULL)
+  {
+    return NULL;
+  }
+
+  return jaw_text_get_gtext_from_string_seq(jniEnv, jStrSeq, start_offset, end_offset);
 }
 
 static gint
diff --git a/wrapper/org/GNOME/Accessibility/AtkText.java b/wrapper/org/GNOME/Accessibility/AtkText.java
index 33da91b..9a828a4 100644
--- a/wrapper/org/GNOME/Accessibility/AtkText.java
+++ b/wrapper/org/GNOME/Accessibility/AtkText.java
@@ -127,6 +127,48 @@ public class AtkText {
                }, null);
        }
 
+       public StringSequence get_text_before_offset (int offset,int boundary_type) {
+               AccessibleText acc_text = _acc_text.get();
+               if (acc_text == null)
+                       return null;
+
+               return AtkUtil.invokeInSwing ( () -> {
+                       if (acc_text instanceof AccessibleExtendedText) {
+                               AccessibleExtendedText acc_ext_text = (AccessibleExtendedText)acc_text;
+                               int part = getPartTypeFromBoundary(boundary_type);
+                               if (part == -1)
+                                       return null;
+                               AccessibleTextSequence seq = acc_ext_text.getTextSequenceBefore(part, offset);
+                               if (seq == null)
+                                       return null;
+                               return new StringSequence(seq.text, seq.startIndex, seq.endIndex+1);
+                       } else {
+                               return private_get_text_at_offset(offset, boundary_type);
+                       }
+               }, null);
+       }
+
+       public StringSequence get_text_after_offset (int offset,int boundary_type) {
+               AccessibleText acc_text = _acc_text.get();
+               if (acc_text == null)
+                       return null;
+
+               return AtkUtil.invokeInSwing ( () -> {
+                       if (acc_text instanceof AccessibleExtendedText) {
+                               AccessibleExtendedText acc_ext_text = (AccessibleExtendedText)acc_text;
+                               int part = getPartTypeFromBoundary(boundary_type);
+                               if (part == -1)
+                                       return null;
+                               AccessibleTextSequence seq = acc_ext_text.getTextSequenceAfter(part, offset);
+                               if (seq == null)
+                                       return null;
+                               return new StringSequence(seq.text, seq.startIndex, seq.endIndex+1);
+                       } else {
+                               return private_get_text_at_offset(offset, boundary_type);
+                       }
+               }, null);
+       }
+
        public int get_caret_offset () {
                AccessibleText acc_text = _acc_text.get();
                if (acc_text == null)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]