[evolution-patches] Re: Patches for gtkhtml, fix several ximian bugzilla bugs
- From: Radek Doulik <rodo ximian com>
- To: Meng-Jie Yu Sun COM
- Cc: Patches <evolution-patches ximian com>
- Subject: [evolution-patches] Re: Patches for gtkhtml, fix several ximian bugzilla bugs
- Date: Tue, 07 Dec 2004 17:00:04 +0100
Hi
Mengjie Yu,
I reviewed part of your patches, which I commented below. For next round of reviewing it please split your patches so that I have one patch per a bug. It would be best if you can resend it as different mails to e-p mailing list.
Cheers
Radek
Index: html.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/a11y/html.c,v
retrieving revision 1.5
diff -u -p -r1.5 html.c
--- html.c 19 Nov 2004 10:19:51 -0000 1.5
+++ html.c 1 Dec 2004 12:28:06 -0000
@@ -200,6 +200,7 @@ html_a11y_ref_state_set (AtkObject *acce
atk_state_set_add_state (state_set, ATK_STATE_VISIBLE);
atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
+ atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
/* printf ("html_a11y_ref_state_set resolves to %p\n", state_set); */
@@ -211,6 +212,11 @@ html_a11y_get_n_children (AtkObject *acc
{
HTMLObject *parent;
gint n_children = 0;
+ AtkStateSet * ss;
+
+ ss = html_a11y_ref_state_set (accessible);
+ if (atk_state_set_contains_state (ss, ATK_STATE_DEFUNCT))
+ return 0;
should unref ss after used
parent = HTML_A11Y_HTML (accessible);
if (parent) {
@@ -227,6 +233,12 @@ html_a11y_ref_child (AtkObject *accessib
{
HTMLObject *parent, *child;
AtkObject *accessible_child = NULL;
+
+ AtkStateSet * ss;
+
+ ss = html_a11y_ref_state_set(accessible);
+ if (atk_state_set_contains_state (ss, ATK_STATE_DEFUNCT))
+ return NULL;
same here
parent = HTML_A11Y_HTML (accessible);
if (parent) {
Index: object.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/a11y/object.c,v
retrieving revision 1.5
diff -u -p -r1.5 object.c
--- object.c 26 May 2004 02:26:17 -0000 1.5
+++ object.c 1 Dec 2004 12:28:09 -0000
@@ -20,7 +20,6 @@
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
-
#include "gtkhtml.h"
#include "htmlengine.h"
#include "htmlobject.h"
@@ -29,12 +28,114 @@
#include "paragraph.h"
#include "utils.h"
#include "text.h"
+#include <glib/gi18n.h>
+#include <atk/atkstateset.h>
static void gtk_html_a11y_class_init (GtkHTMLA11YClass *klass);
static void gtk_html_a11y_init (GtkHTMLA11Y *a11y);
static GtkAccessibleClass *parent_class = NULL;
+
+static gint
+get_n_actions (AtkAction *action)
+{
+ return 1;
+}
+
+static G_CONST_RETURN gchar*
+get_description (AtkAction *action,
+ gint i)
+{
+ if (i == 0)
+ return "grab";
it should be more descriptive
+
+ return NULL;
+}
+
+static G_CONST_RETURN gchar*
+action_get_name (AtkAction *action, gint i)
+{
+ if (i == 0)
+ return "grab";
I think it should be rather named "grab focus"
+
+ return NULL;
+}
+
+
+static uint action_idle_handler = 0;
+static gboolean
+idle_do_action (gpointer data)
+{
+ GtkHTMLA11Y * a11y;
+ GtkWidget *widget;
+
+ action_idle_handler = 0;
+
+ a11y = GTK_HTML_A11Y (data);
+ widget = GTK_ACCESSIBLE (a11y)->widget;
+ if (widget == NULL) {
+ /*
+ * State is defunct
+ */
+ return FALSE;
+ }
+
+ if (!GTK_WIDGET_SENSITIVE (widget) || !GTK_WIDGET_VISIBLE (widget)) {
+ return FALSE;
+ }
+
+ gtk_widget_grab_focus (widget);
+
+ return FALSE;
+}
+
+static gboolean
+do_action (AtkAction * action, gint i)
+{
+ GtkHTMLA11Y * a11y;
+ GtkWidget *widget;
+ gboolean return_value = TRUE;
+
+ a11y = GTK_HTML_A11Y (action);
+ widget = GTK_ACCESSIBLE (action)->widget;
+
+ if (widget == NULL) {
+ /*
+ * State is defunct
+ */
+ return FALSE;
+ }
+
+ if (!GTK_WIDGET_SENSITIVE (widget) || !GTK_WIDGET_VISIBLE (widget))
+ return FALSE;
+
+
+ switch (i) {
+ case 0:
+ if (action_idle_handler)
+ return_value = FALSE;
+ else
+ action_idle_handler = g_idle_add (idle_do_action, a11y);
why do you use idle handler?
+ break;
+ default:
+ return_value = FALSE;
+ break;
+ }
+ return return_value;
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->do_action = do_action;
+ iface->get_n_actions = get_n_actions;
+ iface->get_description = get_description;
+ iface->get_name = action_get_name;
+}
+
GType
gtk_html_a11y_get_type (void)
{
@@ -54,6 +155,12 @@ gtk_html_a11y_get_type (void)
NULL /* value table */
};
+ static const GInterfaceInfo atk_action_info = {
+ (GInterfaceInitFunc) atk_action_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
/*
* Figure out the size of the class and instance
* we are deriving from
@@ -69,6 +176,8 @@ gtk_html_a11y_get_type (void)
tinfo.instance_size = query.instance_size;
type = g_type_register_static (derived_atk_type, "GtkHTMLA11Y", &tinfo, 0);
+
+ g_type_add_interface_static (type, ATK_TYPE_ACTION, &atk_action_info);
}
return type;
@@ -90,15 +199,39 @@ gtk_html_a11y_initialize (AtkObject *obj
g_object_set_data (G_OBJECT (obj), GTK_HTML_ID, data);
}
+
static gint
gtk_html_a11y_get_n_children (AtkObject *accessible)
{
HTMLObject *clue;
gint n_children = 0;
+ AtkStateSet *ss;
+
+ if (GTK_HTML_A11Y_GTKHTML (accessible)->engine->parsing)
+ return 0;
+
+ ss = atk_object_ref_state_set (accessible);
+ if (atk_state_set_contains_state (ss, ATK_STATE_DEFUNCT)) {
+ g_object_unref (ss);
+ return 0;
+ }
+ g_object_unref (ss);
clue = GTK_HTML_A11Y_GTKHTML (accessible)->engine->clue;
- if (clue)
+ if (clue) {
+ AtkObject *atk_clue = html_utils_get_accessible (clue, NULL);
+ if (atk_clue) {
+ AtkStateSet *ss_clue = atk_object_ref_state_set (atk_clue);
+ if (atk_state_set_contains_state (ss_clue, ATK_STATE_DEFUNCT)) {
+ g_object_unref (ss_clue);
+ return 0;
+ }
+ g_object_unref (ss_clue);
+ }
+
n_children = html_object_get_n_children (GTK_HTML_A11Y_GTKHTML (accessible)->engine->clue);
+ }
+
/* printf ("gtk_html_a11y_get_n_children resolves to %d\n", n_children); */
@@ -110,8 +243,29 @@ gtk_html_a11y_ref_child (AtkObject *acce
{
HTMLObject *child;
AtkObject *accessible_child = NULL;
-
+ AtkStateSet *ss;
+
+ if (GTK_HTML_A11Y_GTKHTML (accessible)->engine->parsing)
+ return NULL;
+
+ ss = atk_object_ref_state_set (accessible);
+ if (atk_state_set_contains_state (ss, ATK_STATE_DEFUNCT)) {
+ g_object_unref (ss);
+ return NULL;
+ }
+ g_object_unref (ss);
+
if (GTK_HTML_A11Y_GTKHTML (accessible)->engine->clue) {
+ AtkObject *atk_clue = html_utils_get_accessible (GTK_HTML_A11Y_GTKHTML (accessible)->engine->clue, NULL);
+ if (atk_clue) {
+ AtkStateSet *ss_clue = atk_object_ref_state_set (atk_clue);
+ if (atk_state_set_contains_state (ss_clue, ATK_STATE_DEFUNCT)) {
+ g_object_unref (ss_clue);
+ return NULL;
+ }
+ g_object_unref (ss_clue);
+ }
+
child = html_object_get_child (GTK_HTML_A11Y_GTKHTML (accessible)->engine->clue, index);
if (child) {
accessible_child = html_utils_get_accessible (child, accessible);
@@ -125,6 +279,16 @@ gtk_html_a11y_ref_child (AtkObject *acce
return accessible_child;
}
+static G_CONST_RETURN gchar*
+gtk_html_a11y_get_name (AtkObject *obj)
+{
+ G_CONST_RETURN gchar *name;
+ if (obj->name != NULL && strcmp (obj->name, "")) {
no need to call strcmp, *obj->name is enough. why do you even look if it's non empty. isn't it possible to give atkobject name of empty string?
+ return obj->name;
+ }
+ return _("HTML Container");
+}
+
static void
gtk_html_a11y_class_init (GtkHTMLA11YClass *klass)
{
@@ -136,6 +300,7 @@ gtk_html_a11y_class_init (GtkHTMLA11YCla
atk_class->initialize = gtk_html_a11y_initialize;
atk_class->get_n_children = gtk_html_a11y_get_n_children;
atk_class->ref_child = gtk_html_a11y_ref_child;
+ atk_class->get_name = gtk_html_a11y_get_name;
gobject_class->finalize = gtk_html_a11y_finalize;
}
@@ -178,11 +343,18 @@ gtk_html_a11y_grab_focus_cb(GtkWidget *
}
+static AtkObject * prev_object = NULL;
+
+struct idle_data {
+ AtkObject * a11y;
+ int pos;
+ int len;
+};
+
static void
gtk_html_a11y_cursor_move_cb(GtkWidget *widget, GtkDirectionType dir_type, GtkHTMLCursorSkipType skip)
{
AtkObject *focus_object, *obj;
- static AtkObject * prev_object = NULL;
focus_object = gtk_html_a11y_get_focus_object (widget);
obj = gtk_widget_get_accessible (widget);
@@ -201,6 +373,98 @@ gtk_html_a11y_cursor_move_cb(GtkWidget *
}
}
+static gboolean
+idle_notify_insert (gpointer data)
+{
+ struct idle_data * id = (struct idle_data*)(data);
+
+ if (id != NULL) {
+ HTMLA11YText * text = HTML_A11Y_TEXT (id->a11y);
+ text->insert_idle_handler = 0;
+ g_signal_emit_by_name (id->a11y, "text_changed::insert", id->pos, id->len);
+ }
+ g_free (id);
+
+ return FALSE;
+}
+
+static gboolean
+idle_notify_delete (gpointer data)
+{
+ struct idle_data * id = (struct idle_data*)(data);
+ if (id != NULL) {
+ HTMLA11YText *text = HTML_A11Y_TEXT (id->a11y);
+ text->delete_idle_handler = 0;
+ g_signal_emit_by_name (id->a11y, "text_changed::delete", id->pos, id->len);
+ }
+ g_free (id);
+
+ return FALSE;
+}
again, why do you this in idle handlers?
+static void
+gtk_html_a11y_insert_object_cb (GtkWidget * widget, int pos, int len)
+{
+ AtkObject * a11y, *obj;
+ HTMLText * text;
+
+ obj = gtk_widget_get_accessible (widget);
+ a11y = gtk_html_a11y_get_focus_object (widget);
+
+ if (prev_object != a11y) {
+ prev_object = a11y;
+ g_object_set_data (G_OBJECT(obj), "gail-focus-object", a11y);
+ atk_focus_tracker_notify (a11y);
+ }
+
+ if (G_IS_HTML_A11Y_TEXT(a11y)) {
+ HTMLA11YText * text = HTML_A11Y_TEXT (a11y);
+ struct idle_data * id = g_malloc (sizeof (struct idle_data));
+
+ id->a11y = a11y;
+ id->pos = pos;
+ id->len = len;
+ if (text->insert_idle_handler) {
+ g_free (text->insert_data);
+ g_source_remove (text->insert_idle_handler);
+ }
+
+ text->insert_idle_handler = g_idle_add (idle_notify_insert, id);
+ text->insert_data = id;
+ }
+}
+
+static void
+gtk_html_a11y_delete_object_cb (GtkWidget * widget, int pos, int len)
+{
+ AtkObject * a11y, *obj;
+ HTMLText * text;
+
+ obj = gtk_widget_get_accessible (widget);
+ a11y = gtk_html_a11y_get_focus_object (widget);
+
+ if (prev_object != a11y) {
+ prev_object = a11y;
+ g_object_set_data (G_OBJECT(obj), "gail-focus-object", a11y);
+ atk_focus_tracker_notify (a11y);
+ }
+
+ if (G_IS_HTML_A11Y_TEXT(a11y)) {
+ HTMLA11YText * text = HTML_A11Y_TEXT (a11y);
+
+ struct idle_data * id = g_malloc (sizeof (struct idle_data));
+ id->a11y = a11y;
+ id->pos = pos;
+ id->len = len;
+ if (text->delete_idle_handler) {
+ g_free (text->delete_data);
+ g_source_remove (text->delete_idle_handler);
+ }
+ text->delete_idle_handler = g_idle_add (idle_notify_delete, id);
+ text->delete_data = id;
+ }
+}
+
AtkObject*
gtk_html_a11y_new (GtkWidget *widget)
{
@@ -214,13 +478,20 @@ gtk_html_a11y_new (GtkWidget *widget)
accessible = ATK_OBJECT (object);
atk_object_initialize (accessible, widget);
- accessible->role = ATK_ROLE_HTML_CONTAINER;
+ accessible->role = ATK_ROLE_PANEL;
g_signal_connect_after(widget, "grab_focus",
G_CALLBACK (gtk_html_a11y_grab_focus_cb),
NULL);
g_signal_connect_after(widget, "cursor_move",
G_CALLBACK(gtk_html_a11y_cursor_move_cb),
NULL);
+ g_signal_connect_after(widget, "object_inserted",
+ G_CALLBACK(gtk_html_a11y_insert_object_cb),
+ NULL);
+ g_signal_connect_after(widget, "object_deleted",
+ G_CALLBACK(gtk_html_a11y_delete_object_cb),
+ NULL);
+
html_utils_get_accessible(GTK_HTML(widget)->engine->clue, accessible);
/* printf ("created new gtkhtml accessible object\n"); */
Index: table.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/a11y/table.c,v
retrieving revision 1.2
diff -u -p -r1.2 table.c
--- table.c 1 Nov 2002 15:34:27 -0000 1.2
+++ table.c 1 Dec 2004 12:28:12 -0000
@@ -26,8 +26,11 @@
#include "htmltable.h"
#include "htmltablecell.h"
+#include "gtkhtml.h"
+#include "htmlengine.h"
#include "html.h"
+#include "object.h"
#include "table.h"
#include "utils.h"
@@ -149,6 +152,30 @@ html_a11y_table_new (HTMLObject *html_ob
return accessible;
}
+static gboolean
+is_valid (AtkObject *table)
+{
+ GtkHTMLA11Y * htmla11y = html_a11y_get_gtkhtml_parent (HTML_A11Y (table));
+ GtkHTML *html = GTK_HTML_A11Y_GTKHTML (htmla11y);
+ AtkStateSet *ss;
+
+ HTMLTable *to = HTML_TABLE (HTML_A11Y_HTML (table));
+ if (!to)
+ return FALSE;
+
+ if (html->engine->parsing)
+ return FALSE;
+
+ ss = atk_object_ref_state_set (ATK_OBJECT (htmla11y));
+ if (atk_state_set_contains_state (ss, ATK_STATE_DEFUNCT)) {
+ g_object_unref (ss);
+ return FALSE;
+ }
+ g_object_unref (ss);
+
+ return TRUE;
+}
+
/*
* AtkTable interface
*/
@@ -160,6 +187,10 @@ html_a11y_table_ref_at (AtkTable *table,
HTMLTable *to = HTML_TABLE (HTML_A11Y_HTML (table));
HTMLTableCell *cell;
+
+ if (!is_valid (ATK_OBJECT (table)))
+ return NULL;
+
g_return_val_if_fail (row < to->totalRows, NULL);
g_return_val_if_fail (column < to->totalCols, NULL);
@@ -179,6 +210,9 @@ html_a11y_table_get_index_at (AtkTable *
{
HTMLTable *to = HTML_TABLE (HTML_A11Y_HTML (table));
+ if (!is_valid (ATK_OBJECT (table)))
+ return -1;
+
g_return_val_if_fail (row < to->totalRows, -1);
g_return_val_if_fail (column < to->totalCols, -1);
g_return_val_if_fail (to->cells [row][column], -1);
@@ -192,6 +226,9 @@ html_a11y_table_get_column_at_index (Atk
HTMLTable *to = HTML_TABLE (HTML_A11Y_HTML (table));
HTMLTableCell *cell;
+ if (!is_valid (ATK_OBJECT (table)))
+ return -1;
+
cell = HTML_TABLE_CELL (html_object_get_child (HTML_OBJECT (to), index));
return cell ? cell->col : -1;
@@ -203,6 +240,9 @@ html_a11y_table_get_row_at_index (AtkTab
HTMLTable *to = HTML_TABLE (HTML_A11Y_HTML (table));
HTMLTableCell *cell;
+ if (!is_valid (ATK_OBJECT (table)))
+ return -1;
+
cell = HTML_TABLE_CELL (html_object_get_child (HTML_OBJECT (to), index));
return cell ? cell->row : -1;
@@ -213,6 +253,9 @@ html_a11y_table_get_n_columns (AtkTable
{
HTMLTable *to = HTML_TABLE (HTML_A11Y_HTML (table));
+ if (!is_valid (ATK_OBJECT (table)))
+ return -1;
+
return to->totalCols;
}
@@ -221,6 +264,9 @@ html_a11y_table_get_n_rows (AtkTable *ta
{
HTMLTable *to = HTML_TABLE (HTML_A11Y_HTML (table));
+ if (!is_valid (ATK_OBJECT (table)))
+ return -1;
+
return to->totalRows;
}
@@ -229,6 +275,9 @@ html_a11y_table_get_column_extent_at (At
{
HTMLTable *to = HTML_TABLE (HTML_A11Y_HTML (table));
+ if (!is_valid (ATK_OBJECT (table)))
+ return -1;
+
g_return_val_if_fail (row < to->totalRows, -1);
g_return_val_if_fail (column < to->totalCols, -1);
g_return_val_if_fail (to->cells [row][column], -1);
@@ -241,6 +290,9 @@ html_a11y_table_get_row_extent_at (AtkTa
{
HTMLTable *to = HTML_TABLE (HTML_A11Y_HTML (table));
+ if (!is_valid (ATK_OBJECT (table)))
+ return -1;
+
g_return_val_if_fail (row < to->totalRows, -1);
g_return_val_if_fail (column < to->totalCols, -1);
g_return_val_if_fail (to->cells [row][column], -1);
@@ -254,6 +306,9 @@ html_a11y_table_get_column_header (AtkTa
{
HTMLTable *to = HTML_TABLE (HTML_A11Y_HTML (table));
+ if (!is_valid (ATK_OBJECT (table)))
+ return NULL;
+
g_return_val_if_fail (column < to->totalCols, NULL);
g_return_val_if_fail (to->cells [0][column], NULL);
@@ -265,6 +320,9 @@ static AtkObject *
html_a11y_table_get_row_header (AtkTable *table, gint row)
{
HTMLTable *to = HTML_TABLE (HTML_A11Y_HTML (table));
+
+ if (!is_valid (ATK_OBJECT (table)))
+ return NULL;
g_return_val_if_fail (row < to->totalRows, NULL);
g_return_val_if_fail (to->cells [row][0], NULL);
Index: text.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/a11y/text.c,v
retrieving revision 1.10
diff -u -p -r1.10 text.c
--- text.c 9 Aug 2004 05:50:30 -0000 1.10
+++ text.c 1 Dec 2004 12:28:19 -0000
@@ -24,6 +24,7 @@
#include <config.h>
#include <atk/atkcomponent.h>
#include <atk/atktext.h>
+#include <glib/gi18n.h>
#include "gtkhtml.h"
#include "htmlengine.h"
@@ -48,6 +49,8 @@ static void atk_text_interface_init
static void html_a11y_text_get_extents (AtkComponent *component,
gint *x, gint *y, gint *width, gint *height, AtkCoordType coord_type);
static void html_a11y_text_get_size (AtkComponent *component, gint *width, gint *height);
+static gboolean html_a11y_text_grab_focus (AtkComponent *comp);
+
static gchar * html_a11y_text_get_text (AtkText *text, gint start_offset, gint end_offset);
static gchar * html_a11y_text_get_text_after_offset (AtkText *text, gint offset, AtkTextBoundary boundary_type,
gint *start_offset, gint *end_offset);
@@ -87,9 +90,45 @@ static void html_a11y_text_paste_text (A
static AtkStateSet* html_a11y_text_ref_state_set (AtkObject *accessible);
-
static AtkObjectClass *parent_class = NULL;
+static gint
+get_n_actions (AtkAction *action)
+{
+ return 1;
+}
+
+static G_CONST_RETURN gchar*
+action_get_name (AtkAction *action, gint i)
+{
+ if (i == 0)
+ return _("grab focus");
+
+ return NULL;
+}
+
+static gboolean
+do_action (AtkAction * action, gint i)
+{
+ switch (i) {
+ case 0:
+ return html_a11y_text_grab_focus (ATK_COMPONENT (action));
+ default:
+ return FALSE;
+ }
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->do_action = do_action;
+ iface->get_n_actions = get_n_actions;
+ iface->get_name = action_get_name;
+}
+
+
GType
html_a11y_text_get_type (void)
{
@@ -128,10 +167,18 @@ html_a11y_text_get_type (void)
NULL
};
+ static const GInterfaceInfo atk_action_info = {
+ (GInterfaceInitFunc) atk_action_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+
type = g_type_register_static (G_TYPE_HTML_A11Y, "HTMLA11YText", &tinfo, 0);
g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info);
g_type_add_interface_static (type, ATK_TYPE_TEXT, &atk_text_info);
g_type_add_interface_static (type, ATK_TYPE_EDITABLE_TEXT, &atk_editable_text_info);
+ g_type_add_interface_static (type, ATK_TYPE_ACTION, &atk_action_info);
}
return type;
@@ -144,6 +191,7 @@ atk_component_interface_init (AtkCompone
iface->get_extents = html_a11y_text_get_extents;
iface->get_size = html_a11y_text_get_size;
+ iface->grab_focus = html_a11y_text_grab_focus;
}
static void
@@ -169,6 +217,23 @@ atk_text_interface_init (AtkTextIface *i
static void
html_a11y_text_finalize (GObject *obj)
{
+ HTMLA11YText *text= HTML_A11Y_TEXT (obj);
+
+ g_print ("text object finalize got called\n");
+
+ if (text->insert_idle_handler) {
+ g_source_remove (text->insert_idle_handler);
+ text->insert_idle_handler = 0;
+ g_free (text->insert_data);
+ }
+
+ if (text->delete_idle_handler) {
+ g_source_remove (text->insert_idle_handler);
+ text->insert_idle_handler = 0;
+ g_free (text->delete_data);
+ }
+
+ G_OBJECT_CLASS (parent_class)->finalize (obj);
}
static void
@@ -248,7 +313,8 @@ html_a11y_text_ref_state_set (AtkObject
atk_state_set_add_state (state_set, ATK_STATE_EDITABLE);
atk_state_set_add_state (state_set, ATK_STATE_MULTI_LINE);
- atk_state_set_add_state (state_set, ATK_STATE_MULTI_LINE);
+ atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE);
return state_set;
}
@@ -295,6 +361,19 @@ html_a11y_text_get_size (AtkComponent *c
html_a11y_get_size (component, width, height);
get_size (obj, width, height);
+}
+
+static gboolean
+html_a11y_text_grab_focus (AtkComponent *comp)
+{
+ GtkHTML *html;
+
+ html = GTK_HTML_A11Y_GTKHTML (html_a11y_get_gtkhtml_parent (HTML_A11Y (comp)));
+ g_return_val_if_fail (html && html->engine && html_engine_get_editable (html->engine), FALSE);
+
+ g_signal_emit_by_name (html, "grab_focus");
+
+ return TRUE;
}
/*
Index: text.h
===================================================================
RCS file: /cvs/gnome/gtkhtml/a11y/text.h,v
retrieving revision 1.2
diff -u -p -r1.2 text.h
--- text.h 1 Nov 2002 15:34:27 -0000 1.2
+++ text.h 1 Dec 2004 12:28:19 -0000
@@ -46,6 +46,10 @@ struct _HTMLA11YText {
HTMLA11Y html_a11y_object;
GailTextUtil *util;
+ guint insert_idle_handler;
+ gpointer insert_data;
+ guint delete_idle_handler;
+ gpointer delete_data;
};
GType html_a11y_text_get_type (void);
Index: utils.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/a11y/utils.c,v
retrieving revision 1.5
diff -u -p -r1.5 utils.c
--- utils.c 1 Sep 2003 04:43:40 -0000 1.5
+++ utils.c 1 Dec 2004 12:28:20 -0000
@@ -88,7 +88,13 @@ create_accessible (HTMLObject *o, AtkObj
static void
acc_unref(gpointer data)
{
+ AtkStateSet * ss;
+
g_object_set_data(G_OBJECT(data), HTML_ID, NULL);
+ ss = atk_object_ref_state_set (data);
+
+ atk_state_set_add_state (ss, ATK_STATE_DEFUNCT);
+ atk_object_notify_state_change (data, ATK_STATE_DEFUNCT, TRUE);
g_object_unref(G_OBJECT(data));
}
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/ChangeLog,v
retrieving revision 1.2060
diff -u -p -r1.2060 ChangeLog
--- ChangeLog 29 Nov 2004 15:53:09 -0000 1.2060
+++ ChangeLog 1 Dec 2004 12:55:02 -0000
@@ -1,3 +1,38 @@
+2004-12-01 Mengjie Yu <meng-jie yu sun com>
+
+ * gtkhtml.c: (key_press_event), (focus), (gtk_html_class_init):
+ fix #70078 Add new signals when for insert/delete
+ fix #70085 he focus object may be a frame or an iframe, if so,
+ we must check its focus object recursively.
+ fix #70086 emit "cursor_move" signal when changing cursor's
+ positon
+
+ * gtkhtml.h:
+ fix #70078 add signal field
+
+ * htmlembedded.c: (html_embedded_set_widget):
+ set the a11y name for the widget's atk object.
+
+ * htmlengine-edit-cut-and-paste.c: (insert_object_for_undo),
+ (html_engine_delete):
+ fix #70078 emit signal when insert/delete objects
+
+ * htmlengine-edit-table.c: (delete_column_undo_action):
+ fix #70084 Before doing undo, we need move the cursor back
+ to original position.
+
+ * htmlengine.c: (html_engine_parse):
+ fix #70083 We need to set engine is parsing before all
+ content are destroied.
+
+ * htmlinterval.c: (do_downtree_lines_intersection),
+ (html_interval_forall):
+ fix #70084 add more judgement to avoid crash.
+
+ * htmltext.c: (html_text_get_slave_at_offset):
+ fix #70087 fixes the wrong behaviour when offset is at the end
+ of non-last line of a paragraph
+
2004-11-29 Radek Doulik <rodo ximian com>
* htmlengine.c: make sure we free whole array from g_strsplit
Index: gtkhtml.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/gtkhtml.c,v
retrieving revision 1.582
diff -u -p -r1.582 gtkhtml.c
--- gtkhtml.c 19 Nov 2004 10:19:52 -0000 1.582
+++ gtkhtml.c 1 Dec 2004 12:55:23 -0000
@@ -124,6 +124,9 @@ enum {
SCROLL,
CURSOR_MOVE,
COMMAND,
+ CURSOR_CHANGED,
+ OBJECT_INSERTED,
+ OBJECT_DELETED,
/* now only last signal */
LAST_SIGNAL
};
@@ -866,6 +869,7 @@ key_press_event (GtkWidget *widget, GdkE
GtkHTML *html = GTK_HTML (widget);
GtkHTMLClass *html_class = GTK_HTML_CLASS (GTK_WIDGET_GET_CLASS (html));
gboolean retval, update = TRUE;
+ HTMLEngine *e;
html->binding_handled = FALSE;
html->priv->update_styles = FALSE;
@@ -898,9 +902,20 @@ key_press_event (GtkWidget *widget, GdkE
switch (event->keyval) {
case GDK_Return:
case GDK_KP_Enter:
- if (html->engine->focus_object) {
+ e = html->engine;
+ /* the toplevel gtkhtml's focus object may be a frame or ifame */
+ while (e->focus_object) {
+ if (HTML_IS_FRAME (e->focus_object))
+ e = GTK_HTML (HTML_FRAME (e->focus_object)->html)->engine;
+ else if (HTML_IS_IFRAME (e->focus_object))
+ e = GTK_HTML (HTML_IFRAME (e->focus_object)->html)->engine;
+ else
+ break;
+ }
use html_engine_get_top_html_engine here instead of duplicating code
+ if (e->focus_object) {
gchar *url;
- url = "" (html->engine->focus_object, html->engine->focus_object_offset);
+ url = "" (e->focus_object, e->focus_object_offset);
if (url) {
/* printf ("link clicked: %s\n", url); */
g_signal_emit (html, signals [LINK_CLICKED], 0, url);
@@ -2339,6 +2354,8 @@ focus (GtkWidget *w, GtkDirectionType di
gtk_widget_grab_focus (w);
if (e->caret_mode)
html_engine_jump_to_object (e, obj, offset);
+ g_signal_emit (GTK_HTML (w), signals [CURSOR_MOVE], 0,
+ direction, GTK_HTML_CURSOR_SKIP_ALL);
this looks completely wrong. why do you want to move to end of document here?
return TRUE;
}
@@ -2878,6 +2895,34 @@ gtk_html_class_init (GtkHTMLClass *klass
g_cclosure_marshal_VOID__ENUM,
G_TYPE_NONE, 1, GTK_TYPE_HTML_COMMAND);
+ signals [CURSOR_CHANGED] =
+ g_signal_new ("cursor_changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkHTMLClass, cursor_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals [OBJECT_INSERTED] =
+ g_signal_new ("object_inserted",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkHTMLClass, text_inserted),
+ NULL, NULL,
+ html_g_cclosure_marshal_VOID__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT, G_TYPE_INT);
+
+ signals [OBJECT_DELETED] =
+ g_signal_new ("object_deleted",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkHTMLClass, text_deleted),
+ NULL, NULL,
+ html_g_cclosure_marshal_VOID__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT, G_TYPE_INT);
object_class->destroy = destroy;
Index: gtkhtml.h
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/gtkhtml.h,v
retrieving revision 1.154
diff -u -p -r1.154 gtkhtml.h
--- gtkhtml.h 1 Nov 2004 12:20:26 -0000 1.154
+++ gtkhtml.h 1 Dec 2004 12:55:25 -0000
@@ -101,6 +101,9 @@ struct _GtkHTMLClass {
gfloat position);
void (* cursor_move) (GtkHTML *html, GtkDirectionType dir_type, GtkHTMLCursorSkipType skip);
gboolean (* command) (GtkHTML *html, GtkHTMLCommandType com_type);
+ void (* cursor_changed) (GtkHTML *html);
+ void (* text_inserted) (GtkHTML *html, int pos, int len);
+ void (* text_deleted) (GtkHTML *html, int pos, int len);
so is it text insert/delete or object insert/delete. you should use the same name for signal id and signal callback.
/* properties */
GtkHTMLClassProperties *properties;
Index: htmlembedded.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlembedded.c,v
retrieving revision 1.54
diff -u -p -r1.54 htmlembedded.c
--- htmlembedded.c 19 Nov 2004 10:19:52 -0000 1.54
+++ htmlembedded.c 1 Dec 2004 12:55:26 -0000
@@ -395,10 +395,17 @@ html_embedded_allocate (GtkWidget *w, Gt
void
html_embedded_set_widget (HTMLEmbedded *emb, GtkWidget *w)
{
+ AtkObject *a11y;
emb->widget = w;
d (printf ("set embedded widget: %p widget: %p\n", emb, w));
gtk_widget_show (w);
+
+ if (emb->name) {
+ a11y = gtk_widget_get_accessible (w);
+ if ((a11y != NULL) && (atk_object_get_name (a11y) == NULL))
+ atk_object_set_name (a11y, emb->name);
+ }
there should be no a11y code in gtkhtml/src. please move that stuff to gtkhtml/a11y
g_object_set_data (G_OBJECT (w), "embeddedelement", emb);
g_signal_connect (w, "size_allocate", G_CALLBACK (html_embedded_allocate), emb);
Index: htmlengine-edit-cut-and-paste.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlengine-edit-cut-and-paste.c,v
retrieving revision 1.104
diff -u -p -r1.104 htmlengine-edit-cut-and-paste.c
--- htmlengine-edit-cut-and-paste.c 10 Nov 2004 17:23:42 -0000 1.104
+++ htmlengine-edit-cut-and-paste.c 1 Dec 2004 12:55:34 -0000
@@ -1076,6 +1076,7 @@ insert_object_for_undo (HTMLEngine *e, H
html_cursor_jump_to_position_no_spell (e->cursor, e, position_after + (delete_paragraph_before ? 1 : 0));
insert_setup_undo (e, len, position_before + (delete_paragraph_before ? 1 : 0),
dir, delete_paragraph_before, delete_paragraph_after);
+ g_signal_emit_by_name (e->widget, "object_inserted", position_before, len);
}
static void
@@ -1710,6 +1711,8 @@ html_engine_delete (HTMLEngine *e)
HTMLCursor *start = html_cursor_dup (e->mark->position < e->cursor->position ? e->mark : e->cursor);
HTMLCursor *end = html_cursor_dup (e->mark->position < e->cursor->position ? e->cursor : e->mark);
gint start_position = start->position;
+ gint end_position = end->position;
+
while (start->position < end->position) {
if (start->object->parent->parent == end->object->parent->parent) {
@@ -1755,6 +1758,11 @@ html_engine_delete (HTMLEngine *e)
if (end)
html_cursor_destroy (end);
html_cursor_jump_to_position (e->cursor, e, start_position);
+
+ if (end_position - start_position > 0) {
+ int len = end_position - start_position;
+ g_signal_emit_by_name (e->widget, "object_deleted", start_position, len);
+ }
}
html_undo_level_end (e->undo);
}
Index: htmlengine-edit-table.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlengine-edit-table.c,v
retrieving revision 1.75
diff -u -p -r1.75 htmlengine-edit-table.c
--- htmlengine-edit-table.c 20 Apr 2004 09:57:06 -0000 1.75
+++ htmlengine-edit-table.c 1 Dec 2004 12:55:39 -0000
@@ -340,6 +340,7 @@ delete_column_undo_action (HTMLEngine *e
DeleteCellsUndo *data = "" *) undo_data;
HTMLTable *table;
+ html_cursor_jump_to_position (e->cursor, e, position_after);
table = html_engine_get_table (e);
g_assert (data->size == table->totalRows);
html_table_insert_column (table, e, data->pos, data->cells, html_undo_direction_reverse (dir));
Index: htmlengine.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlengine.c,v
retrieving revision 1.622
diff -u -p -r1.622 htmlengine.c
--- htmlengine.c 29 Nov 2004 15:53:09 -0000 1.622
+++ htmlengine.c 1 Dec 2004 12:56:00 -0000
@@ -4937,6 +4937,7 @@ html_engine_parse (HTMLEngine *e)
{
html_engine_stop_parser (e);
+ e->parsing = TRUE;
/* reset search & replace */
if (e->search_info) {
html_search_destroy (e->search_info);
@@ -4986,7 +4987,6 @@ html_engine_parse (HTMLEngine *e)
e->bgPixmapPtr = NULL;
}
- e->parsing = TRUE;
e->avoid_para = FALSE;
e->timerId = gtk_idle_add ((GtkFunction) html_engine_timer_event, e);
Index: htmlinterval.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmlinterval.c,v
retrieving revision 1.20
diff -u -p -r1.20 htmlinterval.c
--- htmlinterval.c 15 Oct 2003 14:42:23 -0000 1.20
+++ htmlinterval.c 1 Dec 2004 12:56:00 -0000
@@ -218,8 +218,6 @@ get_downtree_line (HTMLObject *o)
static HTMLEngine *
do_downtree_lines_intersection (GSList **l1, GSList **l2, HTMLEngine *e)
{
- g_assert ((*l1)->data == (*l2)->data);
-
while (*l1 && *l2 && (*l1)->data == (*l2)->data) {
e = html_object_get_engine (HTML_OBJECT ((*l1)->data), e);
*l1 = g_slist_remove_link (*l1, *l1);
@@ -292,14 +290,16 @@ html_interval_forall (HTMLInterval *i, H
from_downline = get_downtree_line (i->from.object);
to_downline = get_downtree_line (i->to.object);
- engine = do_downtree_lines_intersection (&from_downline, &to_downline, e);
+ if (from_downline && to_downline) {
+ engine = do_downtree_lines_intersection (&from_downline, &to_downline, e);
- if (from_downline)
- interval_forall (HTML_OBJECT (from_downline->data)->parent, from_downline, to_downline,
- html_object_get_engine (HTML_OBJECT (from_downline->data)->parent, engine), f, data);
- else {
- g_assert (i->from.object == i->to.object);
- html_object_forall (i->from.object, html_object_get_engine (i->from.object, engine), f, data);
+ if (from_downline && HTML_OBJECT (from_downline->data)->parent)
+ interval_forall (HTML_OBJECT (from_downline->data)->parent, from_downline, to_downline,
+ html_object_get_engine (HTML_OBJECT (from_downline->data)->parent, engine), f, data);
+ else {
+ if (i->from.object == i->to.object)
+ html_object_forall (i->from.object, html_object_get_engine (i->from.object, engine), f, data);
+ }
}
g_slist_free (from_downline);
Index: htmltext.c
===================================================================
RCS file: /cvs/gnome/gtkhtml/src/htmltext.c,v
retrieving revision 1.269
diff -u -p -r1.269 htmltext.c
--- htmltext.c 29 Nov 2004 15:53:09 -0000 1.269
+++ htmltext.c 1 Dec 2004 12:56:20 -0000
@@ -2914,8 +2914,7 @@ html_text_get_slave_at_offset (HTMLObjec
while (o && HTML_IS_TEXT_SLAVE (o)) {
if (HTML_IS_TEXT_SLAVE (o) && HTML_TEXT_SLAVE (o)->posStart <= offset
- && (offset < HTML_TEXT_SLAVE (o)->posStart + HTML_TEXT_SLAVE (o)->posLen
- || (offset == HTML_TEXT_SLAVE (o)->posStart + HTML_TEXT_SLAVE (o)->posLen && HTML_TEXT_SLAVE (o)->owner->text_len == offset)))
+ && (offset <= HTML_TEXT_SLAVE (o)->posStart + HTML_TEXT_SLAVE (o)->posLen))
return HTML_TEXT_SLAVE (o);
o = o->next;
}
On Wed, 2004-12-01 at 21:41 -0800, Mengjie Yu wrote:
hi, rodo
Here are some patches about gtkhtml against CVS HEAD.
To better illustrate these patches, I opened several bugs on ximian bugzilla website.
Actually, these bugs had been fixed in our internal CVS tree for days and work well.
Will you please review it ?
Thanks very much
Yours sincerely,
Mengjie Yu
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]