From 030eb06b189f5ff786a5608433c338e5b643d945 Mon Sep 17 00:00:00 2001 From: Tim Wo Date: Wed, 24 Sep 2003 11:26:00 +0000 Subject: some checking code added to ensure that end_offset and start_offset both 2003-09-22 Tim Wo * gal/a11y/e-text/gal-a11y-e-text.c (et_get_text): some checking code added to ensure that end_offset and start_offset both belong to [0, length of the text] and end_offset >= start_offset or it will lead to a crash (et_get_caret_offset):no need to deal with character encoding here, since the widget has already delt with it. (et_get_selection): dealing with character encoding and ensure end_offset >= start_offset, or it will lead to a crash (et_add_selection): we can not get the ETextEventProcessor here, so the old implementation leads to a crash. Modify the parameters "selection_start" and "selection_end" directly instead (et_remove_selection): implementation added (et_set_selection): implementation added (et_set_caret_offset): no need to deal with character encoding here, since the widget has already delt with it. Another change is when offset == -1, move the caret to the end of the text, this keeps the same behavior as GailTextview svn path=/trunk/; revision=22685 --- a11y/e-text/gal-a11y-e-text.c | 163 ++++++++++++++++++++++++++++++------------ 1 file changed, 118 insertions(+), 45 deletions(-) diff --git a/a11y/e-text/gal-a11y-e-text.c b/a11y/e-text/gal-a11y-e-text.c index fe0ae709d1..a37726a5a8 100644 --- a/a11y/e-text/gal-a11y-e-text.c +++ b/a11y/e-text/gal-a11y-e-text.c @@ -109,16 +109,26 @@ et_get_text (AtkText *text, gint start_offset, gint end_offset) { + gint start, end, real_start, real_end, len; const char *full_text = et_get_full_text (text); + if (full_text == NULL) + return; + len = g_utf8_strlen (full_text, -1); + + start = MIN (MAX (0, start_offset), len); + end = MIN (MAX (-1, end_offset), len); if (end_offset == -1) - end_offset = strlen (full_text); + end = strlen (full_text); else - end_offset = g_utf8_offset_to_pointer (full_text, end_offset) - full_text; + end = g_utf8_offset_to_pointer (full_text, end) - full_text; + + start = g_utf8_offset_to_pointer (full_text, start) - full_text; - start_offset = g_utf8_offset_to_pointer (full_text, start_offset) - full_text; + real_start = MIN (start, end); + real_end = MAX (start, end); - return g_strndup (full_text + start_offset, end_offset - start_offset); + return g_strndup (full_text + real_start, real_end - real_start); } static gchar * @@ -170,14 +180,21 @@ et_get_text_before_offset (AtkText *text, static gint et_get_caret_offset (AtkText *text) { - EText *etext = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text))); - const char *full_text = et_get_full_text (text); + GObject *obj; + EText *etext; int offset; + g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE(text), -1); + obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); + if (obj == NULL) + return -1; + + g_return_val_if_fail (E_IS_TEXT (obj), -1); + etext = E_TEXT (obj); + gtk_object_get (GTK_OBJECT (etext), "cursor_pos", &offset, NULL); - offset = g_utf8_pointer_to_offset (full_text, full_text + offset); return offset; } @@ -251,18 +268,29 @@ et_get_selection (AtkText *text, gint *start_offset, gint *end_offset) { - EText *etext = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text))); - if (selection_num == 0 && - etext->selection_start != etext->selection_end) { + gint start, end, real_start, real_end, len; + EText *etext; + if (selection_num == 0) { const char *full_text = et_get_full_text (text); - - if (start_offset) - *start_offset = g_utf8_pointer_to_offset (full_text, full_text + etext->selection_start); - if (end_offset) - *end_offset = g_utf8_pointer_to_offset (full_text, full_text + etext->selection_end); - - return g_strndup (full_text + etext->selection_start, etext->selection_end - etext->selection_start); + if (full_text == NULL) + return NULL; + len = g_utf8_strlen (full_text, -1); + etext = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text))); + start = MIN (etext->selection_start, etext->selection_end); + end = MAX (etext->selection_start, etext->selection_end); + start = MIN (MAX (0, start), len); + end = MIN (MAX (0, end), len); + if (start != end) { + if (start_offset) + *start_offset = start; + if (end_offset) + *end_offset = end; + real_start = g_utf8_offset_to_pointer (full_text, start) - full_text; + real_end = g_utf8_offset_to_pointer (full_text, end) - full_text; + return g_strndup (full_text + real_start, real_end - real_start); + } } + return NULL; } @@ -272,32 +300,36 @@ et_add_selection (AtkText *text, gint start_offset, gint end_offset) { - EText *etext = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text))); - if (etext->selection_start == etext->selection_end && - start_offset != end_offset) { - ETextEventProcessorCommand command; - const char *full_text = et_get_full_text (text); - ETextEventProcessor *tep; + GObject *obj; + EText *etext; - start_offset = g_utf8_offset_to_pointer (full_text, start_offset) - full_text; - end_offset = g_utf8_offset_to_pointer (full_text, end_offset) - full_text; + g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), FALSE); + obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); + if (obj == NULL) + return FALSE; + g_return_val_if_fail (E_IS_TEXT (obj), FALSE); + etext = E_TEXT (obj); - gtk_object_get (GTK_OBJECT (etext), - "tep", &tep, - NULL); + g_return_val_if_fail (start_offset >= 0, FALSE); + g_return_val_if_fail (start_offset >= -1, FALSE); + if (end_offset == -1) + end_offset = et_get_character_count (text); + + if (start_offset != end_offset) { + gint real_start, real_end; + real_start = MIN (start_offset, end_offset); + real_end = MAX (start_offset, end_offset); + etext->selection_start = real_start; + etext->selection_end = real_end; - command.time = gtk_get_current_event_time (); + gnome_canvas_item_grab_focus (GNOME_CANVAS_ITEM (etext)); + gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (etext)); - command.action = E_TEP_MOVE; - command.position = E_TEP_VALUE; - command.value = start_offset; - g_signal_emit_by_name (tep, "command", 0, &command); + g_signal_emit_by_name (ATK_OBJECT (text), "text_selection_changed"); - command.action = E_TEP_SELECT; - command.value = end_offset; - g_signal_emit_by_name (tep, "command", 0, &command); return TRUE; } + return FALSE; } @@ -306,7 +338,23 @@ static gboolean et_remove_selection (AtkText *text, gint selection_num) { - /* Unimplemented */ + GObject *obj; + EText *etext; + + g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), FALSE); + obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); + if (obj == NULL) + return FALSE; + g_return_val_if_fail (E_IS_TEXT (obj), FALSE); + etext = E_TEXT (obj); + + if( selection_num == 0 + && etext->selection_start != etext->selection_end ) { + etext->selection_end = etext->selection_start; + g_signal_emit_by_name (ATK_OBJECT(text), "text_selection_changed"); + return TRUE; + } + return FALSE; } @@ -317,8 +365,19 @@ et_set_selection (AtkText *text, gint start_offset, gint end_offset) { - /* Unimplemented */ - return FALSE; + GObject *obj; + EText *etext; + int offset; + + g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), FALSE); + obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); + if (obj == NULL) + return FALSE; + g_return_val_if_fail (E_IS_TEXT (obj), FALSE); + etext = E_TEXT (obj); + if (selection_num == 0) + return et_add_selection (text, start_offset, end_offset); + return FALSE; } @@ -326,13 +385,27 @@ static gboolean et_set_caret_offset (AtkText *text, gint offset) { - EText *etext = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text))); - const char *full_text = et_get_full_text (text); + GObject *obj; + EText *etext; - offset = g_utf8_offset_to_pointer (full_text, offset) - full_text; - gtk_object_set (GTK_OBJECT (etext), - "cursor_pos", &offset, - NULL); + g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), FALSE); + obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)); + if (obj == NULL) + return FALSE; + + g_return_val_if_fail (E_IS_TEXT (obj), FALSE); + etext = E_TEXT (obj); + + if (offset < -1) + return FALSE; + else if (offset == -1) + gtk_object_set (GTK_OBJECT (etext), + "cursor_pos", et_get_character_count (text), + NULL); + else + gtk_object_set (GTK_OBJECT (etext), + "cursor_pos", offset, + NULL); return TRUE; } -- cgit v1.2.3