Index: ChangeLog
===================================================================
--- ChangeLog	(revision 1299)
+++ ChangeLog	(working copy)
@@ -1,3 +1,9 @@
+2007-11-19  Li Yuan  <li.yuan@sun.com>
+
+	* gail/gailtreeview.c: (gail_tree_view_ref_child):
+	Bug #474504 and #395781. Return a minimally-functional AtkObject
+	when there is no cell in renderer_list.
+
 2007-11-15  Li Yuan  <li.yuan@sun.com>
 
 	* gail/gail.c: (gail_accessibility_module_init):
Index: gail/gailtreeview.c
===================================================================
--- gail/gailtreeview.c	(revision 1299)
+++ gail/gailtreeview.c	(working copy)
@@ -930,14 +930,7 @@
 
   /* If there are more than one renderer in the list, make a container */
 
-  /* XXX FIXME: The code below avoids SEGV but it also avoids the issue;
-   * probably we should be returning minimally-functional AtkObject instances
-   * instead.  See bugzilla.gnome.org #331042.
-   */
-  if (renderer_list == NULL)
-    return NULL;
-
-  if (renderer_list->next)
+  if (renderer_list && renderer_list->next)
     {
       GailCell *container_cell;
 
@@ -962,71 +955,109 @@
 
   child = NULL;
 
-  for (l = renderer_list; l; l = l->next)
+  /*
+   * Now we make a fake cell_renderer if there is no cell in renderer_list
+   */
+
+  if (renderer_list == NULL)
+  {
+    GtkCellRenderer *fake_renderer;
+    fake_renderer = g_object_new (GTK_TYPE_CELL_RENDERER_TEXT, NULL);
+    default_registry = atk_get_default_registry ();
+    factory = atk_registry_get_factory (default_registry,
+                                        GTK_OBJECT_TYPE (fake_renderer));
+    child = atk_object_factory_create_accessible (factory,
+                                                  G_OBJECT (fake_renderer));
+    gail_return_val_if_fail (GAIL_IS_RENDERER_CELL (child), NULL);
+    cell = GAIL_CELL (child);
+    renderer_cell = GAIL_RENDERER_CELL (child);
+    renderer_cell->renderer = fake_renderer;
+
+    /* Create the GailTreeViewCellInfo structure for this cell */
+    cell_info_new (gailview, tree_model, path, tv_col, cell);
+
+    gail_cell_init (cell,
+                    widget, parent, 
+                    i);
+
+    cell->refresh_index = refresh_cell_index;
+
+    /* set state if it is expandable */
+    if (is_expander)
     {
-      renderer = GTK_CELL_RENDERER (l->data);
-    
-      if (GTK_IS_CELL_RENDERER_TEXT (renderer))
-        g_object_get (G_OBJECT (renderer), "editable", &editable, NULL);
+      set_cell_expandable (cell);
+      if (is_expanded)
+        gail_cell_add_state (cell, 
+                             ATK_STATE_EXPANDED,
+                             FALSE);
+    }
+  } else {
+    for (l = renderer_list; l; l = l->next)
+      {
+        renderer = GTK_CELL_RENDERER (l->data);
 
-      default_registry = atk_get_default_registry ();
-      factory = atk_registry_get_factory (default_registry,
-                                          GTK_OBJECT_TYPE (renderer));
-      child = atk_object_factory_create_accessible (factory,
-                                                    G_OBJECT (renderer));
-      gail_return_val_if_fail (GAIL_IS_RENDERER_CELL (child), NULL);
-      cell = GAIL_CELL (child);
-      renderer_cell = GAIL_RENDERER_CELL (child);
+        if (GTK_IS_CELL_RENDERER_TEXT (renderer))
+          g_object_get (G_OBJECT (renderer), "editable", &editable, NULL);
 
-      /* Create the GailTreeViewCellInfo structure for this cell */
-      cell_info_new (gailview, tree_model, path, tv_col, cell);
+        default_registry = atk_get_default_registry ();
+        factory = atk_registry_get_factory (default_registry,
+                                            GTK_OBJECT_TYPE (renderer));
+        child = atk_object_factory_create_accessible (factory,
+                                                      G_OBJECT (renderer));
+        gail_return_val_if_fail (GAIL_IS_RENDERER_CELL (child), NULL);
+        cell = GAIL_CELL (child);
+        renderer_cell = GAIL_RENDERER_CELL (child);
 
-      gail_cell_init (cell,
-                      widget, parent, 
-                      i);
+        /* Create the GailTreeViewCellInfo structure for this cell */
+        cell_info_new (gailview, tree_model, path, tv_col, cell);
 
-      if (container)
-        gail_container_cell_add_child (container, cell);
-      else
-        cell->refresh_index = refresh_cell_index;
+        gail_cell_init (cell,
+                        widget, parent, 
+                        i);
 
-      update_cell_value (renderer_cell, gailview, FALSE);
-      /* Add the actions appropriate for this cell */
-      add_cell_actions (cell, editable);
-  
-      /* set state if it is expandable */
-      if (is_expander)
-        {
-          set_cell_expandable (cell);
-          if (is_expanded)
-            gail_cell_add_state (cell, 
-                                 ATK_STATE_EXPANDED,
-                                 FALSE);
-        }
-      /*
-       * If the column is visible, sets the cell's state
-       */
-      if (gtk_tree_view_column_get_visible (tv_col))
-        set_cell_visibility (tree_view, cell, tv_col, path, FALSE);
-      /*
-       * If the row is selected, all cells on the row are selected
-       */
-      selection = gtk_tree_view_get_selection (tree_view);
+        if (container)
+          gail_container_cell_add_child (container, cell);
+        else
+          cell->refresh_index = refresh_cell_index;
 
-      if (gtk_tree_selection_path_is_selected (selection, path))
-        gail_cell_add_state (cell, ATK_STATE_SELECTED, FALSE);
+        update_cell_value (renderer_cell, gailview, FALSE);
+        /* Add the actions appropriate for this cell */
+        add_cell_actions (cell, editable);
 
-      gail_cell_add_state (cell, ATK_STATE_FOCUSABLE, FALSE);
-      if (focus_index == i)
-        {
-          gailview->focus_cell = g_object_ref (cell);
-          gail_cell_add_state (cell, ATK_STATE_FOCUSED, FALSE);
-        }
-    }
-  g_list_free (renderer_list); 
-  if (container)
-    child =  ATK_OBJECT (container);
+        /* set state if it is expandable */
+        if (is_expander)
+          {
+            set_cell_expandable (cell);
+            if (is_expanded)
+              gail_cell_add_state (cell, 
+                                   ATK_STATE_EXPANDED,
+                                   FALSE);
+          }
+        /*
+         * If the column is visible, sets the cell's state
+         */
+        if (gtk_tree_view_column_get_visible (tv_col))
+          set_cell_visibility (tree_view, cell, tv_col, path, FALSE);
+        /*
+         * If the row is selected, all cells on the row are selected
+         */
+        selection = gtk_tree_view_get_selection (tree_view);
 
+        if (gtk_tree_selection_path_is_selected (selection, path))
+          gail_cell_add_state (cell, ATK_STATE_SELECTED, FALSE);
+
+        gail_cell_add_state (cell, ATK_STATE_FOCUSABLE, FALSE);
+        if (focus_index == i)
+          {
+            gailview->focus_cell = g_object_ref (cell);
+            gail_cell_add_state (cell, ATK_STATE_FOCUSED, FALSE);
+          }
+      }
+    g_list_free (renderer_list); 
+    if (container)
+      child =  ATK_OBJECT (container);
+  } 
+
   if (expander_tv == tv_col)
     {
       AtkRelationSet *relation_set;
