[evolution-patches] seek review for patch for bug 47033 and bug 47034: a11y impl for e-text
- From: Tianyu Tim-Wo <tim wo sun com>
- To: Mike Kestner <mkestner ximian com>
- Cc: "MailList_evolution-patches lists ximian com" <evolution-patches ximian com>, MailList_sceri-evolution-acc sun com
- Subject: [evolution-patches] seek review for patch for bug 47033 and bug 47034: a11y impl for e-text
- Date: Wed, 03 Sep 2003 22:50:03 +0800
Hi Mike,
This is the patch for bug 47033 and bug 47034.
Those 2 bugs are both related to a11y implementation for e-text.
Details please see the ChangeLog in the patch.
The patch could work with gal-a11y-branch and is checked into that
branch by Gilbert.
Since we are going to sync the a11y-branch with HEAD, could you
please take look at this patch. We hope it can be checked into HEAD
before the sync process begins (This weekend)
Thank you very much.
--
Tim Wo <tim wo sun com>
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gal/ChangeLog,v
retrieving revision 1.803
diff -u -r1.803 ChangeLog
--- ChangeLog 21 Aug 2003 01:27:09 -0000 1.803
+++ ChangeLog 3 Sep 2003 14:29:19 -0000
@@ -1,3 +1,35 @@
+2003-09-01 Tim Wo <tim wo sun com>
+ * gal/a11y/e-text/gal-a11y-e-text-factory.h: GalA11yETextFactory should inherit from AtkObjectFactory, not AtkObject. (#47097).
+ * gal/a11y/e-text/gal-a11y-e-text-factory.c: (gal_a11y_e_text_factory_create_accessible) the role of the atk objectshould be set in the initializaion function of gal-a11y-e-text
+ * gal/e-text/e-text.c (e_text_class_init): Added registration code for GalA11yETextFactory. (#47097)
+ * gal/a11y/e-text/gal-a11y-e-text.c: (#47033, #47034) some type check code added in most functions since we use runtime inheritance and we can't determine which class are we inheritance fromduring compile time.
+ (et_get_character_at_offset): moved to the front of the file to fit theorder of functions defined in AtkText
+ (et_get_text): some check code added to ensure end_offset >=start_offset or it will crash
+ (is_a_seperator, find_word_start, find_word_end, find_sentence_start, find_sentence_end
+ find_line_start, find_line_end): 7 new private function add. They are all used by text retrieving functions.
+ (et_get_text_after_offset): newly implemented function
+ (et_get_text_at_offset): newly implemented function
+ (et_get_text_before_offset): newly implemented function
+ (et_get_caret_offset): no need to dela with character encoding here,the widget has already delt with it
+ (et_get_character_extents): newly implemented function
+ (et_get_offset_at_point): newly implemented function
+ (et_get_selection): deal with character encoding and ensure end_offset>= start_offset
+ (et_add_selection): changed the original implementation, the old onelead to a crash
+ (et_remove_selection): newly implemented function
+ (et_set_selection): newly implemented function
+ (et_set_caret_offset): no need to dela with character encoding here,the widget has already delt with it. if offset == 1 then move to the endof the text (same behavior as GailTextview)
+ (et_get_range_extents): new functions to be implemented which isdefined in AtkText
+ (et_get_bounded_ranges): new functions to be implemented which isdefined in AtkText
+ (et_copy_text): newly implemented function
+ (et_delete_text): newly implemented function
+ (et_cut_text): newly implemented function
+ (et_paste_text): newly implemented function
+ (et_atk_text_iface_init): add entrance for 2 functions(et_get_range_extents and et_get_bounded_ranges)
+ (_et_change_cb): newly added callback handler for text change
+ (et_real_initialize): newly added function to deal with initialization
+ (et_class_init): overwrite the virtual function "initialize" in AtkObject with "et_real_initialize"
+ Set value for "component_parent_iface". (#47097)
+
2003-08-20 Suresh Chandrasekharan <suresh chandrasekharan sun com>
* gal/util/e-util.c (e_filename_make_safe): Fix for 47474
Index: gal/a11y/e-text/gal-a11y-e-text-factory.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-text/gal-a11y-e-text-factory.c,v
retrieving revision 1.1
diff -u -r1.1 gal-a11y-e-text-factory.c
--- gal/a11y/e-text/gal-a11y-e-text-factory.c 30 Nov 2002 07:54:16 -0000 1.1
+++ gal/a11y/e-text/gal-a11y-e-text-factory.c 3 Sep 2003 14:29:21 -0000
@@ -32,7 +32,6 @@
atk_object = g_object_new (GAL_A11Y_TYPE_E_TEXT, NULL);
atk_object_initialize (atk_object, obj);
- atk_object->role = ATK_ROLE_UNKNOWN;
return atk_object;
}
Index: gal/a11y/e-text/gal-a11y-e-text-factory.h
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-text/gal-a11y-e-text-factory.h,v
retrieving revision 1.1
diff -u -r1.1 gal-a11y-e-text-factory.h
--- gal/a11y/e-text/gal-a11y-e-text-factory.h 30 Nov 2002 07:54:16 -0000 1.1
+++ gal/a11y/e-text/gal-a11y-e-text-factory.h 3 Sep 2003 14:29:21 -0000
@@ -22,11 +22,11 @@
typedef struct _GalA11yETextFactoryClass GalA11yETextFactoryClass;
struct _GalA11yETextFactory {
- AtkObject object;
+ AtkObjectFactory object;
};
struct _GalA11yETextFactoryClass {
- AtkObjectClass parent_class;
+ AtkObjectFactoryClass parent_class;
};
Index: gal/a11y/e-text/gal-a11y-e-text.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-text/gal-a11y-e-text.c,v
retrieving revision 1.1
diff -u -r1.1 gal-a11y-e-text.c
--- gal/a11y/e-text/gal-a11y-e-text.c 30 Nov 2002 07:54:16 -0000 1.1
+++ gal/a11y/e-text/gal-a11y-e-text.c 3 Sep 2003 14:29:28 -0000
@@ -2,6 +2,7 @@
/*
* Authors:
* Christopher James Lahey <clahey ximian com>
+ * Tim Wo <tim wo sun com>, Sun Microsystem Inc. 2003.
*
* Copyright (C) 2002 Ximian, Inc.
*/
@@ -48,12 +49,24 @@
gint *height,
AtkCoordType coord_type)
{
- EText *item = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (component)));
+ GObject *obj;
+ EText *item;
+
double real_width;
double real_height;
int fake_width;
int fake_height;
+ g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (component));
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (component));
+
+ if (obj == NULL)
+ /* item is defunct */
+ return;
+
+ g_return_if_fail( E_IS_TEXT (obj));
+ item = E_TEXT(obj);
+
if (component_parent_iface &&
component_parent_iface->get_extents)
component_parent_iface->get_extents (component,
@@ -77,10 +90,21 @@
static const gchar *
et_get_full_text (AtkText *text)
{
- EText *etext = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)));
+ GObject *obj;
+ EText *etext;
ETextModel *model;
const char *full_text;
+ g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), NULL);
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+
+ if (obj == NULL)
+ /* item is defunct */
+ return NULL;
+
+ g_return_val_if_fail (E_IS_TEXT (obj), NULL);
+ etext = E_TEXT(obj);
+
gtk_object_get (GTK_OBJECT (etext),
"model", &model,
NULL);
@@ -94,9 +118,20 @@
et_set_full_text (AtkEditableText *text,
const char *full_text)
{
- EText *etext = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)));
+ GObject *obj;
+ EText *etext;
ETextModel *model;
+ g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text));
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+
+ if (obj == NULL)
+ /* item is defunct */
+ return;
+
+ g_return_if_fail (E_IS_TEXT (obj));
+ etext = E_TEXT(obj);
+
gtk_object_get (GTK_OBJECT (etext),
"model", &model,
NULL);
@@ -104,21 +139,201 @@
e_text_model_set_text (model, full_text);
}
+static gunichar
+et_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ const char *full_text = et_get_full_text (text);
+ char *at_offset;
+
+ if( full_text == NULL )
+ return 0;
+
+ at_offset = g_utf8_offset_to_pointer (full_text, offset);
+ return g_utf8_get_char_validated (at_offset, -1);
+}
+
static gchar *
et_get_text (AtkText *text,
gint start_offset,
gint end_offset)
{
+ gint start, end;
const char *full_text = et_get_full_text (text);
-
+
+ g_return_val_if_fail( full_text, NULL );
+ g_return_val_if_fail( start_offset >= 0, NULL );
+ g_return_val_if_fail( end_offset >= 0 || end_offset == -1, NULL );
+
if (end_offset == -1)
- end_offset = strlen (full_text);
+ end_offset = g_utf8_strlen (full_text, -1);
else
end_offset = g_utf8_offset_to_pointer (full_text, end_offset) - full_text;
start_offset = g_utf8_offset_to_pointer (full_text, start_offset) - full_text;
- return g_strndup (full_text + start_offset, end_offset - start_offset);
+ start = MIN( start_offset, end_offset );
+ end = MAX( start_offset, end_offset );
+
+ return g_strndup (full_text + start, end - start);
+}
+
+static gboolean
+is_a_seperator( gunichar c )
+{
+ /* FIXME: In some case 'ispunct' can't work correctly when given character is a chinese one. */
+ return ispunct(c) || isspace(c);
+}
+
+static gint
+find_word_start (const char *text,
+ gint begin_offset,
+ gint step)
+{
+ gint offset;
+ char *at_offset;
+ gunichar current, previous;
+ offset = begin_offset;
+ gint len = g_utf8_strlen (text, -1);
+
+ while (offset > 0 && offset < len)
+ {
+ at_offset = g_utf8_offset_to_pointer (text, offset);
+ current = g_utf8_get_char_validated (at_offset, -1);
+ at_offset = g_utf8_offset_to_pointer (text, offset-1 );
+ previous = g_utf8_get_char_validated (at_offset, -1);
+ if ( ! is_a_seperator(current)
+ && is_a_seperator(previous))
+ break;
+ offset += step;
+ }
+
+ return offset;
+}
+
+static gint
+find_word_end (const char *text,
+ gint begin_offset,
+ gint step)
+{
+
+ gint offset;
+ char *at_offset;
+ gunichar current, previous;
+ offset = begin_offset;
+ gint len = g_utf8_strlen (text, -1);
+
+ while (offset > 0 && offset < len)
+ {
+ at_offset = g_utf8_offset_to_pointer (text, offset);
+ current = g_utf8_get_char_validated (at_offset, -1);
+ at_offset = g_utf8_offset_to_pointer (text, offset-1);
+ previous = g_utf8_get_char_validated (at_offset, -1);
+ if (is_a_seperator(current)
+ && ! is_a_seperator(previous))
+ break;
+ offset += step;
+ }
+
+ return offset;
+}
+
+static gint
+find_sentence_start (const char *text,
+ gint begin_offset,
+ gint step)
+{
+ /* FIXME: the function won't work correctly when step > 0 */
+ gint offset, sentence_start;
+ char *at_offset;
+ gunichar current;
+ offset = begin_offset;
+ sentence_start = -1;
+ gint len = g_utf8_strlen (text, -1);
+
+ while (TRUE)
+ {
+ if (offset <= 0 || offset >= len)
+ {
+ sentence_start = offset;
+ break;
+ }
+ at_offset = g_utf8_offset_to_pointer (text, offset);
+ current = g_utf8_get_char_validated (at_offset, -1);
+ if (isalnum (current))
+ sentence_start = offset;
+ if ((current == '.' || current == '!' || current == '?')
+ && (sentence_start != -1))
+ break;
+ offset += step;
+ }
+ return sentence_start;
+}
+
+static gint
+find_sentence_end (const char *text,
+ gint begin_offset,
+ gint step)
+{
+ gint offset;
+ char *at_offset;
+ gunichar previous;
+ offset = begin_offset;
+ gint len = g_utf8_strlen (text, -1);
+
+ while (offset > 0 && offset < len)
+ {
+ at_offset = g_utf8_offset_to_pointer (text, offset-1);
+ previous = g_utf8_get_char_validated (at_offset, -1);
+ if ((previous == '.' || previous == '!' || previous == '?'))
+ break;
+ offset += step;
+ }
+ return offset;
+}
+
+static gint
+find_line_start (const char *text,
+ gint begin_offset,
+ gint step)
+{
+ gint offset;
+ char *at_offset;
+ gunichar previous;
+ offset = begin_offset;
+ gint len = g_utf8_strlen (text, -1);
+
+ while (offset > 0 && offset < len)
+ {
+ at_offset = g_utf8_offset_to_pointer (text, offset-1);
+ previous = g_utf8_get_char_validated (at_offset, -1);
+ if (previous == '\n' || previous == '\r')
+ break;
+ offset += step;
+ }
+ return offset;
+}
+
+static gint
+find_line_end (const char *text,
+ gint begin_offset,
+ gint step)
+{
+ gint offset;
+ char *at_offset;
+ gunichar current;
+ offset = begin_offset;
+ gint len = g_utf8_strlen (text, -1);
+
+ while (offset >= 0 && offset < len)
+ {
+ at_offset = g_utf8_offset_to_pointer (text, offset);
+ current = g_utf8_get_char_validated (at_offset, -1);
+ if (current == '\n' || current == '\r')
+ break;
+ offset += step;
+ }
+ return offset;
}
static gchar *
@@ -128,8 +343,55 @@
gint *start_offset,
gint *end_offset)
{
- /* Unimplemented */
- return NULL;
+ gint start=0, end=0;
+ const char *full_text = et_get_full_text (text);
+ g_return_val_if_fail( full_text, NULL );
+
+ if (boundary_type == ATK_TEXT_BOUNDARY_CHAR)
+ {
+ start = offset + 1;
+ end = offset + 2;
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_WORD_START)
+ {
+ start = find_word_start (full_text, offset+1, 1);
+ end = find_word_start (full_text, start+1, 1) ;
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_WORD_END)
+ {
+ start = find_word_end (full_text, offset+1, 1);
+ end = find_word_end (full_text, start+1, 1);
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_SENTENCE_START)
+ {
+ start = find_sentence_start (full_text, offset+1, 1);
+ end = find_sentence_start (full_text, start+1, 1) ;
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_SENTENCE_END)
+ {
+ start = find_sentence_end (full_text, offset+1, 1);
+ end = find_sentence_end (full_text, start+1, 1) ;
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START)
+ {
+ start = find_line_start (full_text, offset+1, 1);
+ end = find_line_start (full_text, start+1, 1) ;
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
+ {
+ start = find_line_end (full_text, offset+1, 1);
+ end = find_line_end (full_text, start+1, 1) ;
+ }
+ else
+ return NULL;
+
+ if (start < 0) start = 0;
+ if (end < 0) end = 0;
+ if (start > g_utf8_strlen(full_text, -1)) start = g_utf8_strlen(full_text, -1);
+ if (end > g_utf8_strlen(full_text, -1)) end = g_utf8_strlen(full_text, -1);
+ if (start_offset) *start_offset = start;
+ if (end_offset) *end_offset = end;
+ return et_get_text( text, start, end );
}
static gchar *
@@ -139,22 +401,57 @@
gint *start_offset,
gint *end_offset)
{
- /* Unimplemented */
- return NULL;
-}
-
-static gunichar
-et_get_character_at_offset (AtkText *text,
- gint offset)
-{
- const char *full_text = et_get_full_text (text);
- char *at_offset;
+ gint start=0, end=0;
+ const char *full_text = et_get_full_text (text);
+ g_return_val_if_fail( full_text, NULL );
+
+ if (boundary_type == ATK_TEXT_BOUNDARY_CHAR)
+ {
+ start = offset;
+ end = offset + 1;
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_WORD_START)
+ {
+ start = find_word_start (full_text, offset-1, -1);
+ end = find_word_start (full_text, offset, 1) ;
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_WORD_END)
+ {
+ start = find_word_end (full_text, offset, -1);
+ end = find_word_end (full_text, offset+1, 1);
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_SENTENCE_START)
+ {
+ start = find_sentence_start (full_text, offset-1, -1);
+ end = find_sentence_start (full_text, offset, 1);
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_SENTENCE_END)
+ {
+ start = find_sentence_end (full_text, offset, -1);
+ end = find_sentence_end (full_text, offset+1, 1);
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START)
+ {
+ start = find_line_start (full_text, offset-1, -1);
+ end = find_line_start (full_text, offset, 1);
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
+ {
+ start = find_line_end (full_text, offset, -1);
+ end = find_line_end (full_text, offset+1, 1);
+ }
+ else
+ return NULL;
- at_offset = g_utf8_offset_to_pointer (full_text, offset);
- return g_utf8_get_char_validated (at_offset, -1);
+ if (start < 0) start = 0;
+ if (end < 0) end = 0;
+ if (start > g_utf8_strlen(full_text, -1)) start = g_utf8_strlen(full_text, -1);
+ if (end > g_utf8_strlen(full_text, -1)) end = g_utf8_strlen(full_text, -1);
+ if (start_offset) *start_offset = start;
+ if (end_offset) *end_offset = end;
+ return et_get_text( text, start, end );
}
-
static gchar*
et_get_text_before_offset (AtkText *text,
gint offset,
@@ -162,22 +459,78 @@
gint *start_offset,
gint *end_offset)
{
- /* Unimplemented */
- return NULL;
+ gint start=0, end=0;
+ const char *full_text = et_get_full_text (text);
+ g_return_val_if_fail( full_text, NULL );
+
+ if (boundary_type == ATK_TEXT_BOUNDARY_CHAR)
+ {
+ start = offset - 1;
+ end = offset;
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_WORD_START)
+ {
+ end = find_word_start (full_text, offset-1, -1);
+ start = find_word_start (full_text, end-1, -1) ;
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_WORD_END)
+ {
+ end = find_word_end (full_text, offset, -1);
+ start = find_word_end (full_text, end-1, -1);
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_SENTENCE_START)
+ {
+ end = find_sentence_start (full_text, offset, -1);
+ start = find_sentence_start (full_text, end-1, -1);
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_SENTENCE_END)
+ {
+ end = find_sentence_end (full_text, offset, -1);
+ start = find_sentence_end (full_text, end-1, -1);
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START)
+ {
+ end = find_line_start (full_text, offset, -1);
+ start = find_line_start (full_text, end-1, -1);
+ }
+ else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
+ {
+ end = find_line_end (full_text, offset, -1);
+ start = find_line_end (full_text, end-1, -1);
+ }
+ else
+ return NULL;
+
+ if (start < 0) start = 0;
+ if (end < 0) end = 0;
+ if (start > g_utf8_strlen(full_text, -1)) start = g_utf8_strlen(full_text, -1);
+ if (end > g_utf8_strlen(full_text, -1)) end = g_utf8_strlen(full_text, -1);
+ if (start_offset) *start_offset = start;
+ if (end_offset) *end_offset = end;
+ return et_get_text( text, start, end );
}
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)
+ /* item is defunct */
+ 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;
}
@@ -210,7 +563,76 @@
gint *height,
AtkCoordType coords)
{
- /* Unimplemented */
+ GObject *obj;
+ EText *etext;
+ GnomeCanvas *canvas;
+ gint x_widget, y_widget, x_window, y_window;
+ GdkWindow *window;
+ GtkWidget *widget;
+ int index;
+ int trailing;
+ PangoRectangle pango_pos;
+
+ g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE(text));
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+ if (obj == NULL)
+ /* item is defunct */
+ return;
+
+ g_return_if_fail (E_IS_TEXT (obj));
+ etext = E_TEXT(obj);
+ canvas = GNOME_CANVAS_ITEM(etext)->canvas;
+ widget = GTK_WIDGET(canvas);
+ window = widget->window;
+ gdk_window_get_origin (window, &x_widget, &y_widget);
+
+ pango_layout_index_to_pos (etext->layout, offset, &pango_pos);
+ pango_pos.x = PANGO_PIXELS (pango_pos.x);
+ pango_pos.y = PANGO_PIXELS (pango_pos.y);
+ pango_pos.width = (pango_pos.width + PANGO_SCALE / 2) / PANGO_SCALE;
+ pango_pos.height = (pango_pos.height + PANGO_SCALE / 2) / PANGO_SCALE;
+
+ *x = pango_pos.x + x_widget;
+ *y = pango_pos.y + y_widget;
+
+ *width = pango_pos.width;
+ *height = pango_pos.height;
+
+ if (etext->draw_borders) {
+ *x += 3; /*BORDER_INDENT;*/
+ *y += 3; /*BORDER_INDENT;*/
+ }
+
+ *x += etext->xofs;
+ *y += etext->yofs;
+
+ if (etext->editing) {
+ *x -= etext->xofs_edit;
+ *y -= etext->yofs_edit;
+ }
+
+ *x += etext->cx;
+ *y += etext->cy;
+
+ if (coords == ATK_XY_WINDOW)
+ {
+ window = gdk_window_get_toplevel (window);
+ gdk_window_get_origin (window, &x_window, &y_window);
+ *x -= x_window;
+ *y -= y_window;
+ }
+ else if (coords == ATK_XY_SCREEN)
+ {
+ }
+ else
+ {
+ *x = 0;
+ *y = 0;
+ *height = 0;
+ *width = 0;
+ }
+
+
}
@@ -218,7 +640,10 @@
et_get_character_count (AtkText *text)
{
const char *full_text = et_get_full_text (text);
-
+
+ if( full_text == NULL )
+ return 0;
+
return g_utf8_strlen (full_text, -1);
}
@@ -229,15 +654,88 @@
gint y,
AtkCoordType coords)
{
- /* Unimplemented */
- return 0;
+ GObject *obj;
+ EText *etext;
+ GnomeCanvas *canvas;
+ gint x_widget, y_widget, x_window, y_window;
+ GdkWindow *window;
+ GtkWidget *widget;
+ int index;
+ int trailing;
+
+ g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE(text), -1);
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+ if (obj == NULL)
+ /* item is defunct */
+ return -1;
+
+ g_return_val_if_fail (E_IS_TEXT (obj), -1);
+ etext = E_TEXT(obj);
+ canvas = GNOME_CANVAS_ITEM(etext)->canvas;
+ widget = GTK_WIDGET(canvas);
+
+ window = widget->window;
+ gdk_window_get_origin (window, &x_widget, &y_widget);
+
+ if (coords == ATK_XY_SCREEN)
+ {
+ x = x - x_widget;
+ y = y - y_widget;
+ }
+ else if (coords == ATK_XY_WINDOW)
+ {
+ window = gdk_window_get_toplevel (window);
+ gdk_window_get_origin (window, &x_window, &y_window);
+
+ x = x - x_widget + x_window;
+ y = y - y_widget + y_window;
+ }
+ else
+ return -1;
+
+
+ if (etext->draw_borders) {
+ x -= 3; /*BORDER_INDENT;*/
+ y -= 3; /*BORDER_INDENT;*/
+ }
+
+ x -= etext->xofs;
+ y -= etext->yofs;
+
+ if (etext->editing) {
+ x += etext->xofs_edit;
+ y += etext->yofs_edit;
+ }
+
+ x -= etext->cx;
+ y -= etext->cy;
+
+ pango_layout_xy_to_index (etext->layout,
+ x * PANGO_SCALE - PANGO_SCALE / 2,
+ y * PANGO_SCALE - PANGO_SCALE / 2,
+ &index,
+ &trailing);
+
+ return g_utf8_pointer_to_offset (etext->text, etext->text + index + trailing);
}
static gint
et_get_n_selections (AtkText *text)
{
- EText *etext = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)));
+ GObject *obj;
+ EText *etext;
+
+ g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), 0);
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+
+ if (obj == NULL)
+ /* item is defunct */
+ return 0;
+
+ g_return_val_if_fail (E_IS_TEXT (obj), 0);
+ etext = E_TEXT (obj);
+
if (etext->selection_start !=
etext->selection_end)
return 1;
@@ -251,17 +749,41 @@
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) {
- const char *full_text = et_get_full_text (text);
+ GObject *obj;
+ EText *etext;
+ const char *full_text;
+ gint start, end, real_start, real_end;
+ gint len;
+ g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), NULL);
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+
+ if (obj == NULL)
+ /* item is defunct */
+ return NULL;
+
+ g_return_val_if_fail (E_IS_TEXT (obj), NULL);
+ etext = E_TEXT(obj);
+
+ full_text = et_get_full_text (text);
+ g_return_val_if_fail (full_text, NULL);
+
+ start = MIN( etext->selection_start, etext->selection_end );
+ end = MAX( etext->selection_start, etext->selection_end );
+ len = et_get_character_count(text);
+ if (start > len) start = len;
+ if (end > len) end = len;
+ real_start = g_utf8_offset_to_pointer (full_text, start) - full_text;
+ real_end = g_utf8_offset_to_pointer (full_text, end) - full_text;
+
+ if( selection_num == 0 )
+ {
if (start_offset)
- *start_offset = g_utf8_pointer_to_offset (full_text, full_text + etext->selection_start);
+ *start_offset = 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);
+ *end_offset = end;
+ if (real_start != real_end)
+ return g_strndup (full_text + real_start, real_end - real_start);
}
return NULL;
}
@@ -272,30 +794,38 @@
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));
- gtk_object_get (GTK_OBJECT (etext),
- "tep", &tep,
- NULL);
+ if (obj == NULL)
+ /* item is defunct */
+ return FALSE;
+
+ g_return_val_if_fail (E_IS_TEXT (obj), FALSE);
+ etext = E_TEXT (obj);
+
+ 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;
+
+ gnome_canvas_item_grab_focus(GNOME_CANVAS_ITEM(etext));
+ etext->needs_redraw = 1;
+ gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(etext));
- command.time = gtk_get_current_event_time ();
+ g_signal_emit_by_name (ATK_OBJECT(text), "text_selection_changed");
- command.action = E_TEP_MOVE;
- command.position = E_TEP_VALUE;
- command.value = start_offset;
- g_signal_emit_by_name (tep, "command", 0, &command);
-
- command.action = E_TEP_SELECT;
- command.value = end_offset;
- g_signal_emit_by_name (tep, "command", 0, &command);
return TRUE;
}
return FALSE;
@@ -306,7 +836,32 @@
et_remove_selection (AtkText *text,
gint selection_num)
{
- /* Unimplemented */
+ 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)
+ /* item is defunct */
+ 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 )
+ {
+ gtk_object_get (GTK_OBJECT (etext),
+ "cursor_pos", &offset,
+ NULL);
+
+ etext->selection_start = etext->selection_end = offset;
+
+ g_signal_emit_by_name (ATK_OBJECT(text), "text_selection_changed");
+
+ return TRUE;
+ }
return FALSE;
}
@@ -317,8 +872,25 @@
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)
+ /* item is defunct */
+ 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,16 +898,52 @@
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)
+ /* item is defunct */
+ 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;
}
+static void
+et_get_range_extents (AtkText *text,
+ gint start_offset,
+ gint end_offset,
+ AtkCoordType coord_type,
+ AtkTextRectangle *rect)
+{
+ /* Unimplemented */
+ return;
+}
+
+static AtkTextRange**
+et_get_bounded_ranges (AtkText *text,
+ AtkTextRectangle *rect,
+ AtkCoordType coord_type,
+ AtkTextClipType x_clip_type,
+ AtkTextClipType y_clip_type)
+{
+ /* Unimplemented */
+ return NULL;
+}
+
+
static gboolean
et_set_run_attributes (AtkEditableText *text,
AtkAttributeSet *attrib_set,
@@ -362,6 +970,10 @@
/* Utf8 unimplemented */
const char *full_text = et_get_full_text (ATK_TEXT (text));
+
+ if( full_text == NULL )
+ return;
+
char *result = g_strdup_printf ("%.*s%.*s%s", *position, full_text, length, string, full_text + *position);
et_set_full_text (text, result);
@@ -376,30 +988,80 @@
gint start_pos,
gint end_pos)
{
- /* Unimplemented */
+ GObject *obj;
+ EText *etext;
+
+ g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text));
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+
+ if (obj == NULL)
+ /* item is defunct */
+ return;
+ g_return_if_fail(E_IS_TEXT (obj));
+ etext = E_TEXT (obj);
+
+ if( start_pos != end_pos )
+ {
+ etext->selection_start = start_pos;
+ etext->selection_end = end_pos;
+ e_text_copy_clipboard (etext);
+ }
}
static void
-et_cut_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos)
+et_delete_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
{
- /* Unimplemented */
+ GObject *obj;
+ EText *etext;
+
+ g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE(text));
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+
+ if (obj == NULL)
+ /* item is defunct */
+ return;
+
+ g_return_if_fail (E_IS_TEXT (obj));
+ etext = E_TEXT (obj);
+
+ etext->selection_start = start_pos;
+ etext->selection_end = end_pos;
+
+ e_text_delete_selection(etext);
}
static void
-et_delete_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos)
+et_cut_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
{
- /* Unimplemented */
+ et_copy_text( text, start_pos, end_pos );
+ et_delete_text( text, start_pos, end_pos );
}
static void
et_paste_text (AtkEditableText *text,
gint position)
{
- /* Unimplemented */
+ GObject *obj;
+ EText *etext;
+
+ g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text));
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+
+ if (obj == NULL)
+ /* item is defunct */
+ return;
+
+ g_return_if_fail (E_IS_TEXT (obj));
+ etext = E_TEXT (obj);
+
+ gtk_object_set (GTK_OBJECT (etext),
+ "cursor_pos", position,
+ NULL);
+ e_text_paste_clipboard(etext);
}
@@ -429,6 +1091,8 @@
iface->remove_selection = et_remove_selection;
iface->set_selection = et_set_selection;
iface->set_caret_offset = et_set_caret_offset;
+ iface->get_range_extents = et_get_range_extents;
+ iface->get_bounded_ranges = et_get_bounded_ranges;
}
static void
@@ -444,15 +1108,52 @@
}
static void
-et_class_init (GalA11yETextClass *klass)
+_et_changed_cb (EText *etext,
+ gpointer user_data)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ AtkObject *accessible;
+ AtkText *text;
- quark_accessible_object = g_quark_from_static_string ("gtk-accessible-object");
+ accessible = ATK_OBJECT (user_data);
+ text = ATK_TEXT (accessible);
- parent_class = g_type_class_ref (PARENT_TYPE);
+ g_signal_emit_by_name (text, "text-caret-moved", et_get_caret_offset(text) );
+}
+
+static void
+et_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GalA11yEText *a11y;
+ EText *etext;
+
+ ATK_OBJECT_CLASS (parent_class)->initialize (obj, data);
- object_class->dispose = et_dispose;
+ g_return_if_fail (GAL_A11Y_IS_E_TEXT (obj));
+ g_return_if_fail (E_IS_TEXT (data));
+
+ a11y = GAL_A11Y_E_TEXT (obj);
+ etext = E_TEXT (data);
+
+ /* Set up signal callbacks */
+/* g_signal_connect_data (etext, "keypress",
+ (GCallback) _et_keypress_cb, etext, NULL, 0);
+*/ g_signal_connect_data (etext, "changed",
+ (GCallback) _et_changed_cb, obj, NULL, 0);
+
+ obj->role = ATK_ROLE_TEXT;
+}
+
+static void
+et_class_init (GalA11yETextClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ quark_accessible_object = g_quark_from_static_string ("gtk-accessible-object");
+ parent_class = g_type_class_ref (PARENT_TYPE);
+ component_parent_iface = g_type_interface_peek(parent_class, ATK_TYPE_COMPONENT);
+ object_class->dispose = et_dispose;
+ class->initialize = et_real_initialize;
}
static void
Index: gal/e-text/e-text.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-text/e-text.c,v
retrieving revision 1.146
diff -u -r1.146 e-text.c
--- gal/e-text/e-text.c 13 Aug 2003 05:58:20 -0000 1.146
+++ gal/e-text/e-text.c 3 Sep 2003 14:29:45 -0000
@@ -67,6 +67,9 @@
#include <libart_lgpl/art_rgb.h>
#include <libart_lgpl/art_rgb_bitmap_affine.h>
+#include <atk/atk.h>
+#include "gal/a11y/e-text/gal-a11y-e-text-factory.h"
+
#define PARENT_TYPE (gnome_canvas_item_get_type())
#define BORDER_INDENT 3
@@ -3594,6 +3597,11 @@
if (!clipboard_atom)
clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
+
+ atk_registry_set_factory_type (atk_get_default_registry (),
+ E_TYPE_TEXT,
+ gal_a11y_e_text_factory_get_type ());
+
}
/* Object initialization function for the text item */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]