? tmp
Index: gailwidget.c
===================================================================
RCS file: /cvs/gnome/gail/gail/gailwidget.c,v
retrieving revision 1.71
diff -u -p -r1.71 gailwidget.c
--- gailwidget.c	25 Apr 2003 16:02:00 -0000	1.71
+++ gailwidget.c	9 May 2003 15:55:14 -0000
@@ -33,6 +33,7 @@ static G_CONST_RETURN gchar* gail_widget
 static G_CONST_RETURN gchar* gail_widget_get_description (AtkObject *accessible);
 static AtkObject* gail_widget_get_parent (AtkObject *accessible);
 static AtkStateSet* gail_widget_ref_state_set (AtkObject *accessible);
+static AtkRelationSet* gail_widget_ref_relation_set (AtkObject *accessible);
 static gint gail_widget_get_index_in_parent (AtkObject *accessible);
 
 static void atk_component_interface_init (AtkComponentIface *iface);
@@ -158,6 +159,7 @@ gail_widget_class_init (GailWidgetClass 
   class->get_name = gail_widget_get_name;
   class->get_description = gail_widget_get_description;
   class->get_parent = gail_widget_get_parent;
+  class->ref_relation_set = gail_widget_ref_relation_set;
   class->ref_state_set = gail_widget_ref_state_set;
   class->get_index_in_parent = gail_widget_get_index_in_parent;
   class->initialize = gail_widget_real_initialize;
@@ -339,6 +341,86 @@ gail_widget_get_parent (AtkObject *acces
       parent = gtk_widget_get_accessible (parent_widget);
     }
   return parent;
+}
+
+AtkRelationSet*
+gail_widget_ref_relation_set (AtkObject *obj)
+{
+  GtkWidget *widget;
+  AtkRelationSet *relation_set;
+
+  g_return_val_if_fail (GAIL_IS_WIDGET (obj), NULL);
+
+  widget = GTK_ACCESSIBLE (obj)->widget;
+  if (widget == NULL)
+    /*
+     * State is defunct
+     */
+    return NULL;
+
+  relation_set = ATK_OBJECT_CLASS (parent_class)->ref_relation_set (obj);
+
+  if (!atk_relation_set_contains (relation_set, ATK_RELATION_LABELLED_BY))
+    {
+      /*
+       * Heuristic to create LABELLED_BY relation:
+       *
+       * If the previous or next child of the current widget is a label 
+       * and its mnemonic widget is the current widget then set LABELLED_BY 
+       * relation on current accessible object.
+       */
+      GList *list, *l;
+      GtkWidget *parent;
+      GtkWidget *label;
+      gint index;
+      AtkObject *array[1];
+      AtkRelation* relation;
+
+      parent = gtk_widget_get_parent (widget);
+      if (GTK_IS_CONTAINER (parent))
+        {
+          list = gtk_container_get_children (GTK_CONTAINER (parent));
+
+          l = list;
+          if (l)
+            {
+              while (l)
+                {
+                  if ((GtkWidget *)l->data == widget)
+                    break;
+
+                  l = l->next;
+                }
+              /*
+               * The widget may claim container as parent but it may not
+               * be listed as a child.
+               */
+              g_return_val_if_fail (l, relation_set);
+              if (l->prev && GTK_IS_LABEL (l->prev->data))
+                label = GTK_WIDGET (l->prev->data);
+              else if (l->next && GTK_IS_LABEL (l->next->data))
+                label = GTK_WIDGET (l->next->data);
+              else
+                label = NULL;
+
+              g_list_free (list);
+
+              if (label)
+                {
+                  if (gtk_label_get_mnemonic_widget (GTK_LABEL (label)) == widget)
+                    {
+	              array [0] = gtk_widget_get_accessible (label);
+
+	              relation = atk_relation_new (array, 1, ATK_RELATION_LABELLED_BY);
+	              atk_relation_set_add (relation_set, relation);
+	              g_object_unref (relation);
+                    }
+                }
+            }
+        }
+    }
+
+  return relation_set;
 }
 
 static AtkStateSet*
