Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gal/ChangeLog,v
retrieving revision 1.818
diff -u -r1.818 ChangeLog
--- ChangeLog	3 Nov 2003 06:55:14 -0000	1.818
+++ ChangeLog	4 Nov 2003 06:24:05 -0000
@@ -1,3 +1,23 @@
+2003-11-04  Tim Wo  <tim.wo@sun.com>
+
+	* gal/a11y/e-table/Makefile.am: new files (gal-a11y-e-cell-tree.c/h)
+	added
+	* gal/a11y/e-table/gal-a11y-e-cell.h: adding 2 new functions to add or
+	remove atk states
+	* gal/a11y/e-table/gal-a11y-e-cell.c (eti_dispose): unref the state_set
+	(eti_ref_state_set): new function
+	(eti_class_init): create and initialize the state_set
+	(eti_init): override the "ref_state_set" function in AtkObjectClass with
+	"eti_ref_state_set"
+	(gal_a11y_e_cell_add_state): adding a return value
+	(gal_a11y_e_cell_remove_state): new function
+	* gal/e-table/e-cell-tree.c: (e_cell_tree_class_init): register
+	GalA11yECellText as the a11y implementation for ECellText.
+	* gal/a11y/e-table/gal-a11y-e-cell-tree.c: new file. A11y implementation
+	for ECellTree
+	* gal/a11y/e-table/gal-a11y-e-cell-tree.h: new file. A11y implementation
+	for ECellTree
+
 2003-11-03  Bolian Yin <bolian.yin@sun.com>
                                                                                 
         * gal/a11y/e-table/gal-a11y-e-table-item: defunct widget checking, selection interface
Index: gal/a11y/e-table/Makefile.am
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/Makefile.am,v
retrieving revision 1.4
diff -u -r1.4 Makefile.am
--- gal/a11y/e-table/Makefile.am	28 Oct 2003 05:41:03 -0000	1.4
+++ gal/a11y/e-table/Makefile.am	4 Nov 2003 06:24:06 -0000
@@ -15,6 +15,7 @@
 	gal-a11y-e-tree-factory.c		\
 	gal-a11y-e-cell.c			\
 	gal-a11y-e-cell-text.c			\
+	gal-a11y-e-cell-tree.c			\
 	gal-a11y-e-cell-toggle.c		\
 	gal-a11y-e-cell-registry.c		\
 	gal-a11y-e-table.c			\
@@ -29,6 +30,7 @@
 	gal-a11y-e-tree-factory.h		\
 	gal-a11y-e-cell.h			\
 	gal-a11y-e-cell-text.h			\
+	gal-a11y-e-cell-tree.h			\
 	gal-a11y-e-cell-toggle.h		\
 	gal-a11y-e-cell-registry.h		\
 	gal-a11y-e-table.h			\
Index: gal/a11y/e-table/gal-a11y-e-cell.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-cell.c,v
retrieving revision 1.4
diff -u -r1.4 gal-a11y-e-cell.c
--- gal/a11y/e-table/gal-a11y-e-cell.c	3 Nov 2003 04:20:10 -0000	1.4
+++ gal/a11y/e-table/gal-a11y-e-cell.c	4 Nov 2003 06:24:07 -0000
@@ -57,11 +57,24 @@
 	a11y->view_col = -1;
 	a11y->row = -1;
 
+	if (a11y->state_set)
+		g_object_unref (a11y->state_set);
+
 	if (parent_class->dispose)
 		parent_class->dispose (object);
 }
 
 /* Static functions */
+static AtkStateSet *
+eti_ref_state_set (AtkObject *accessible)
+{
+	GalA11yECell *cell = GAL_A11Y_E_CELL (accessible);
+	g_return_val_if_fail (cell->state_set, NULL);
+
+	g_object_ref(cell->state_set);
+	return cell->state_set;
+}
+
 static AtkObject*
 eti_get_parent (AtkObject *accessible)
 {
@@ -154,6 +167,7 @@
 
 	atk_object_class->get_parent          = eti_get_parent;
 	atk_object_class->get_index_in_parent = eti_get_index_in_parent;
+	atk_object_class->ref_state_set       = eti_ref_state_set;
 }
 
 static void
@@ -165,6 +179,10 @@
 	a11y->model_col = -1;
 	a11y->view_col = -1;
 	a11y->row = -1;
+
+	a11y->state_set = atk_state_set_new ();
+	atk_state_set_add_state (a11y->state_set, ATK_STATE_TRANSIENT);
+	atk_state_set_add_state (a11y->state_set, ATK_STATE_ENABLED);
 }
 
 
@@ -407,9 +425,40 @@
 			if (state_type == ATK_STATE_VISIBLE)
 				g_signal_emit_by_name (cell, "visible_data_changed");
 		}
+
+		return rc;
 	}
+	else
+		return FALSE;
 }
 
+gboolean
+gal_a11y_e_cell_remove_state (GalA11yECell     *cell,
+			      AtkStateType state_type,
+			      gboolean     emit_signal)
+{
+	if (atk_state_set_contains_state (cell->state_set, state_type)) {
+		gboolean rc;
+                                                                                                                              
+		rc = atk_state_set_remove_state (cell->state_set, state_type);
+		/*
+		 * The signal should only be generated if the value changed,
+		 * not when the cell is set up.  So states that are set
+		 * initially should pass FALSE as the emit_signal argument.
+		 */
+
+		if (emit_signal) {
+			atk_object_notify_state_change (ATK_OBJECT (cell), state_type, FALSE);
+			/* If state_type is ATK_STATE_VISIBLE, additional notification */
+			if (state_type == ATK_STATE_VISIBLE)
+				g_signal_emit_by_name (cell, "visible_data_changed");
+		}
+
+		return rc;
+	}
+	else
+		return FALSE;
+}
 
 /**
  * gal_a11y_e_cell_get_type:
@@ -451,6 +500,7 @@
 
 	return type;
 }
+
 AtkObject *
 gal_a11y_e_cell_new (ETableItem *item,
 		     ECellView  *cell_view,
Index: gal/a11y/e-table/gal-a11y-e-cell.h
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-cell.h,v
retrieving revision 1.2
diff -u -r1.2 gal-a11y-e-cell.h
--- gal/a11y/e-table/gal-a11y-e-cell.h	28 Oct 2003 05:41:03 -0000	1.2
+++ gal/a11y/e-table/gal-a11y-e-cell.h	4 Nov 2003 06:24:07 -0000
@@ -87,5 +87,13 @@
 gboolean gal_a11y_e_cell_remove_action_by_name (GalA11yECell        *cell,
                                           	const gchar     *action_name);
 
+gboolean gal_a11y_e_cell_add_state     (GalA11yECell *cell,
+					AtkStateType state_type,
+					gboolean     emit_signal);
+
+gboolean gal_a11y_e_cell_remove_state  (GalA11yECell *cell,
+					AtkStateType state_type,
+					gboolean     emit_signal);
+
 
 #endif /* ! __GAL_A11Y_E_CELL_H__ */
Index: gal/e-table/e-cell-tree.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-cell-tree.c,v
retrieving revision 1.49
diff -u -r1.49 e-cell-tree.c
--- gal/e-table/e-cell-tree.c	19 Aug 2003 17:27:36 -0000	1.49
+++ gal/e-table/e-cell-tree.c	4 Nov 2003 06:24:09 -0000
@@ -52,6 +52,9 @@
 #include "tree-expanded.xpm"
 #include "tree-unexpanded.xpm"
 
+#include "gal/a11y/e-table/gal-a11y-e-cell-registry.h"
+#include "gal/a11y/e-table/gal-a11y-e-cell-tree.h"
+
 #define PARENT_TYPE e_cell_get_type ()
 
 typedef struct {
@@ -828,6 +831,8 @@
 	ecc->get_bg_color     = ect_get_bg_color;
 
 	parent_class = g_type_class_ref (PARENT_TYPE);
+
+        gal_a11y_e_cell_registry_add_cell_type (NULL, E_CELL_TREE_TYPE, gal_a11y_e_cell_tree_new);
 }
 
 E_MAKE_TYPE(e_cell_tree, "ECellTree", ECellTree, e_cell_tree_class_init, NULL, PARENT_TYPE)
--- /dev/null	2002-08-31 07:31:37.000000000 +0800
+++ gal/a11y/e-table/gal-a11y-e-cell-tree.h	2003-11-04 15:06:20.000000000 +0800
@@ -0,0 +1,48 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors:
+ *   Tim Wo <tim.wo@sun.com>, Sun Microsystem Inc. 2003.
+ *
+ * Copyright (C) 2002 Ximian, Inc.
+ */
+
+#ifndef __GAL_A11Y_E_CELL_TREE_H__
+#define __GAL_A11Y_E_CELL_TREE_H__
+
+#include <glib-object.h>
+#include <gal/e-table/e-table-item.h>
+#include <gal/e-table/e-cell-tree.h>
+#include "gal-a11y-e-cell.h"
+
+#define GAL_A11Y_TYPE_E_CELL_TREE            (gal_a11y_e_cell_tree_get_type ())
+#define GAL_A11Y_E_CELL_TREE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL_TREE, GalA11yECellTree))
+#define GAL_A11Y_E_CELL_TREE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_CELL_TREE, GalA11yECellTreeClass))
+#define GAL_A11Y_IS_E_CELL_TREE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL_TREE))
+#define GAL_A11Y_IS_E_CELL_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL_TREE))
+
+typedef struct _GalA11yECellTree GalA11yECellTree;
+typedef struct _GalA11yECellTreeClass GalA11yECellTreeClass;
+typedef struct _GalA11yECellTreePrivate GalA11yECellTreePrivate;
+
+/* This struct should actually be larger as this isn't what we derive from.
+ * The GalA11yECellTreePrivate comes right after the parent class structure.
+ **/
+struct _GalA11yECellTree {
+	GalA11yECell object;
+};
+
+struct _GalA11yECellTreeClass {
+	GalA11yECellClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType      gal_a11y_e_cell_tree_get_type   (void);
+AtkObject *gal_a11y_e_cell_tree_new	   (ETableItem *item,
+					    ECellView  *cell_view,
+					    AtkObject  *parent,
+					    int         model_col,
+					    int         view_col,
+					    int         row);
+
+#endif /* ! __GAL_A11Y_E_CELL_TREE_H__ */
--- /dev/null	2002-08-31 07:31:37.000000000 +0800
+++ gal/a11y/e-table/gal-a11y-e-cell-tree.c	2003-11-04 15:06:20.000000000 +0800
@@ -0,0 +1,142 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: 
+ *   Tim Wo <tim.wo@sun.com>, Sun Microsystem Inc. 2003.
+ *
+ * Copyright (C) 2002 Ximian, Inc.
+ */
+
+#include <config.h>
+#include <atk/atkaction.h>
+#include "gal-a11y-e-cell-tree.h"
+#include "gal-a11y-util.h"
+#include "gal/e-table/e-cell-tree.h"
+#include "gal/e-table/e-table.h"
+#include "gal/e-table/e-tree-table-adapter.h"
+
+#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yECellTreeClass))
+static AtkObjectClass *a11y_parent_class;
+#define A11Y_PARENT_TYPE (gal_a11y_e_cell_get_type ())
+
+static void
+ectr_do_action_expand (AtkAction *action)
+{
+	GalA11yECell *a11y;
+	ETableModel *table_model;
+        ETreePath node;
+	ETreeModel *tree_model;
+        ETreeTableAdapter *tree_table_adapter;
+        
+        a11y = GAL_A11Y_E_CELL (action);
+	table_model = a11y->item->table_model;
+	node = e_table_model_value_at (table_model, -1, a11y->row);
+	tree_model = e_table_model_value_at (table_model, -2, a11y->row);
+	tree_table_adapter = e_table_model_value_at (table_model, -3, a11y->row);
+
+	if (e_tree_model_node_is_expandable (tree_model, node)) {
+		e_tree_table_adapter_node_set_expanded (tree_table_adapter,
+							node,
+							TRUE);
+		gal_a11y_e_cell_add_state (a11y, ATK_STATE_EXPANDED, TRUE);
+	}
+}
+
+static void
+ectr_do_action_collapse (AtkAction *action)
+{
+	GalA11yECell *a11y;
+	ETableModel *table_model;
+        ETreePath node;
+	ETreeModel *tree_model;
+        ETreeTableAdapter *tree_table_adapter;
+        
+        a11y = GAL_A11Y_E_CELL (action);
+	table_model = a11y->item->table_model;
+        node = e_table_model_value_at (table_model, -1, a11y->row);
+	tree_model = e_table_model_value_at (table_model, -2, a11y->row);
+        tree_table_adapter = e_table_model_value_at (table_model, -3, a11y->row);
+
+	if (e_tree_model_node_is_expandable (tree_model, node)) {
+		e_tree_table_adapter_node_set_expanded (tree_table_adapter,
+							node,
+							FALSE);
+		gal_a11y_e_cell_remove_state (a11y, ATK_STATE_EXPANDED, TRUE);
+	}
+}
+
+static void
+ectr_class_init (GalA11yECellTreeClass *klass)
+{
+	a11y_parent_class        = g_type_class_ref (A11Y_PARENT_TYPE);
+}
+
+static void
+ectr_init (GalA11yECellTree *a11y)
+{
+	gal_a11y_e_cell_add_action (a11y,
+				    "expand",
+				    "expands the row in the ETree containing this cell",
+				    NULL,
+				    (ACTION_FUNC)ectr_do_action_expand);
+
+	gal_a11y_e_cell_add_action (a11y,
+				    "collapse",
+				    "collapses the row in the ETree containing this cell",
+				    NULL,
+				    (ACTION_FUNC)ectr_do_action_collapse);
+
+	gal_a11y_e_cell_add_state (a11y, ATK_STATE_EXPANDABLE, FALSE);
+}
+
+GType
+gal_a11y_e_cell_tree_get_type (void)
+{
+	static GType type = 0;
+
+	if (!type) {
+		GTypeInfo info = {
+			sizeof (GalA11yECellTreeClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) ectr_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL, /* class_data */
+			sizeof (GalA11yECellTree),
+			0,
+			(GInstanceInitFunc) ectr_init,
+			NULL /* value_cell_text */
+		};
+
+		type = g_type_register_static (A11Y_PARENT_TYPE, "GalA11yECellTree", &info, 0);
+		gal_a11y_e_cell_type_add_action_interface (type);
+	}
+
+	return type;
+}
+
+AtkObject *
+gal_a11y_e_cell_tree_new (ETableItem *item,
+			  ECellView  *cell_view,
+			  AtkObject  *parent,
+			  int         model_col,
+			  int         view_col,
+			  int         row)
+{
+	GalA11yECell *a11y;
+        GtkWidget *e_table;
+        gint model_row;
+	a11y = g_object_new (gal_a11y_e_cell_tree_get_type (), NULL);
+
+        e_table = gtk_widget_get_parent (GNOME_CANVAS_ITEM (item)->canvas);
+        model_row = e_table_view_to_model_row (E_TABLE (e_table), row);
+
+	gal_a11y_e_cell_construct (a11y,
+				   item,
+				   cell_view,
+				   parent,
+				   model_col,
+				   view_col,
+				   model_row);
+	
+	return a11y;
+}
