Index: gnopernicus/srlow/libsrlow/SRObject.c
===================================================================
RCS file: /cvs/gnome/gnopernicus/srlow/libsrlow/SRObject.c,v
retrieving revision 1.124
diff -u -r1.124 SRObject.c
--- gnopernicus/srlow/libsrlow/SRObject.c	5 Apr 2005 11:29:01 -0000	1.124
+++ gnopernicus/srlow/libsrlow/SRObject.c	15 Apr 2005 12:45:39 -0000
@@ -5470,14 +5470,180 @@
 }
 
 
+#define ACCESSIBLE_RELATION_SET_FREE(rel)		\
+    {							\
+	gint k;						\
+	srl_assert (rel);				\
+	for (k = 0; rel[k]; k++)			\
+	    AccessibleRelation_unref (rel[k]);		\
+	g_free (rel);					\
+    }
+
+static Accessible*
+get_flows_from (Accessible *acc)
+{
+    Accessible *rv = NULL;
+    AccessibleRelation **rel;
+    gint k;
+
+    srl_assert (acc);
+
+    rel = Accessible_getRelationSet (acc);
+    if (!rel)
+	return NULL;
+
+    for (k = 0; rel[k]; k++)
+    {
+	if (SPI_RELATION_FLOWS_FROM == AccessibleRelation_getRelationType (rel[k]))
+	{
+	    if (AccessibleRelation_getNTargets (rel[k]) != 1)
+		srl_warning ("more than one FLOWS_FROM relation");
+	    rv = AccessibleRelation_getTarget (rel[k], 0);
+	    break;
+	}
+    }
+    ACCESSIBLE_RELATION_SET_FREE (rel);
+
+    return rv;
+}
+
+static Accessible*
+get_flows_to (Accessible *acc)
+{
+    Accessible *rv = NULL;
+    AccessibleRelation **rel;
+    gint k;
+
+    srl_assert (acc);
+
+    rel = Accessible_getRelationSet (acc);
+    if (!rel)
+	return NULL;
+
+    for (k = 0; rel[k]; k++)
+    {
+	if (SPI_RELATION_FLOWS_TO == AccessibleRelation_getRelationType (rel[k]))
+	{
+	    if (AccessibleRelation_getNTargets (rel[k]) != 1)
+		srl_warning ("more than one FLOWS_TO relation");
+	    rv = AccessibleRelation_getTarget (rel[k], 0);
+	    break;
+	}
+    }
+    ACCESSIBLE_RELATION_SET_FREE (rel);
+
+    return rv;
+}
+
+
+static void
+get_selected_text_from_flows_from (Accessible *acc,
+				   GString *sel)
+{
+    srl_assert (acc && sel);
+
+    Accessible_ref (acc);
+    
+    do
+    {
+	Accessible *tmp = acc;
+	AccessibleText *text;
+	gint cnt;
+	gboolean last = FALSE;
+
+	acc = get_flows_from (acc);
+	Accessible_unref (tmp);
+	if (!acc)
+	    break;
+	text = Accessible_getText (acc);
+	if (!text)
+	    break;
+	cnt = AccessibleText_getNSelections (text);
+	if (cnt > 0)
+	{
+	    gchar *str = NULL;
+	    long int sp, ep;
+	    AccessibleText_getSelection (text, cnt - 1, &sp, &ep);
+	    if (ep != AccessibleText_getCharacterCount (text)) /* last selection doesn't contain last char */
+	    	last = TRUE;
+	    else
+	    {
+		str = AccessibleText_getText (text,  sp, ep);
+		if (str && str[0])
+		{
+		    g_string_insert (sel, 0, " ");
+		    g_string_insert (sel, 0, str);
+		}
+		SPI_freeString (str);
+	    }
+	}
+	AccessibleText_unref (text);
+	if (last || cnt != 1)
+	    break;
+    }while (TRUE);
+    if (acc)
+	Accessible_unref (acc);
+}
+
+
+static void
+get_selected_text_from_flows_to (Accessible *acc,
+				 GString *sel)
+{
+    srl_assert (acc && sel);
+
+    Accessible_ref (acc);
+    
+    do
+    {
+	Accessible *tmp = acc;
+	AccessibleText *text;
+	gint cnt;
+	gboolean last = FALSE;
+
+	acc = get_flows_to (acc);
+	Accessible_unref (tmp);
+	if (!acc)
+	    break;
+	text = Accessible_getText (acc);
+	if (!text)
+	    break;
+	cnt = AccessibleText_getNSelections (text);
+	if (cnt > 0)
+	{
+	    gchar *str = NULL;
+	    long int sp, ep;
+	    AccessibleText_getSelection (text, 0, &sp, &ep);
+	    if (sp != 0) /* last selection doesn't contain first char */
+	    	last = TRUE;
+	    else
+	    {
+		str = AccessibleText_getText (text,  sp, ep);
+		if (str && str[0])
+		{
+		    g_string_append (sel, " ");
+		    g_string_append (sel, str);
+		}
+		SPI_freeString (str);
+	    }
+	}
+	AccessibleText_unref (text);
+	if (last || cnt != 1)
+	    break;
+    }while (TRUE);
+    if (acc)
+	Accessible_unref (acc);
+}
+
 gboolean 
 sro_text_get_selections (SRObject *obj,
 			 gchar ***selections,
 			 SRLong index)
 {
+    AccessibleText *text;
+    gint cnt, i;
     Accessible *acc;
-    AccessibleText *acc_text;
-    long n_sel;
+
     if (selections)
 	*selections = NULL;
             
@@ -5487,28 +5653,36 @@
     acc = sro_get_acc_at_index (obj, index);
     if (!acc)
 	return FALSE;
-    acc_text = get_text_from_acc (acc);
-    if (!acc_text)
+    text = get_text_from_acc (acc);
+    if (!text)
 	return FALSE;
 
-    n_sel = AccessibleText_getNSelections (acc_text);
-    if (n_sel > 0)
+    cnt = AccessibleText_getNSelections (text);
+    if (cnt > 0)
+    	*selections = g_new (gchar*, cnt + 1);
+
+    for (i = 0; i < cnt; i++)
     {
-	long i;
-	*selections = (gchar**) g_malloc ((n_sel + 1) * sizeof (gchar*));
-	for (i = 0; i < n_sel; i++)
-	{
-	    gchar *tmp;
-	    long int start, end;
-	    AccessibleText_getSelection (acc_text, i, &start, &end);
-	    tmp = AccessibleText_getText (acc_text, start, end);
-	    (*selections)[i] = SR_strdup (tmp);
-	    SPI_freeString (tmp);
-	}
-	(*selections)[n_sel] = NULL;
+	long int sp, ep;
+	gchar *str = NULL;
+	GString *sel;
+
+	sel = g_string_new ("");
+	AccessibleText_getSelection (text, i, &sp, &ep);
+        if (sp == 0)
+	    get_selected_text_from_flows_from (acc, sel);
+        str = AccessibleText_getText (text,  sp, ep);
+        g_string_append (sel, " ");
+        g_string_append (sel, str ? str : "");
+        SPI_freeString (str);
+        if (ep == AccessibleText_getCharacterCount (text))
+    	    get_selected_text_from_flows_to (acc, sel);
+	(*selections)[i] = SR_strdup (sel->str);
+	g_string_free (sel, TRUE);
     }
+    (*selections)[cnt] = NULL;
 
-    AccessibleText_unref (acc_text);    
+    AccessibleText_unref (text);
     return *selections ? TRUE : FALSE;    
 }
 
