/* collection.c: implements the Collection interface */
#include <config.h>
+#include <glib.h>
#include <stdio.h>
#include <bonobo/bonobo-exception.h>
+#include <libspi/accessible.h>
#include <libspi/collection.h>
#include <libspi/matchrule.h>
+#include <libspi/stateset.h>
#include <libspi/spi-private.h>
-typedef struct _MatchRulePrivate MatchRulePrivate;
-
-struct _MatchRulePrivate {
-
- Accessibility_StateSet states;
- Accessibility_Collection_MatchType statematchtype;
- Accessibility_AttributeSet *attributes;
- Accessibility_Collection_MatchType attributematchtype;
- Accessibility_RoleSet *roles;
- Accessibility_Collection_MatchType rolematchtype;
- CORBA_char *interfaces;
- Accessibility_Collection_MatchType interfacematchtype;
- gboolean invert;
-
-};
-
-#define MATCH_RULE_PRIVATE(o)\
- G_TYPE_INSTANCE_GET_PRIVATE((o), SPI_MATCHRULE_TYPE, MatchRulePrivate)
-
-
SpiCollection *
-spi_collection_interface_new ()
+spi_collection_interface_new (AtkObject *obj)
{
-
SpiCollection *new_collection = g_object_new (SPI_COLLECTION_TYPE, NULL);
+ spi_base_construct (SPI_BASE (new_collection), G_OBJECT (obj));
+
+ return new_collection;
+}
- spi_base_construct_default (SPI_BASE (new_collection));
+static AtkObject *
+get_atkobject_from_servant (PortableServer_Servant servant){
- return new_collection;
+ SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
+ g_return_val_if_fail (object, NULL);
+ g_return_val_if_fail (ATK_IS_OBJECT (object->gobj), NULL);
+
+ return ATK_OBJECT (object->gobj);
}
-/*
static SpiCollection *
get_collection_from_servant (PortableServer_Servant servant)
{
SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
g_return_val_if_fail (object, NULL);
-
- return SPI_COLLECTION (object->gobj);
-
+ g_return_val_if_fail (IS_COLLECTION (object), NULL);
+
+ return SPI_COLLECTION (object);
}
-*/
static Accessibility_MatchRule
impl_createMatchRule (PortableServer_Servant servant,
- const Accessibility_StateSet states,
- const Accessibility_Collection_MatchType statematchtype,
- const Accessibility_AttributeSet *attributes,
- const Accessibility_Collection_MatchType attributematchtype,
- const Accessibility_RoleSet *roles,
- const Accessibility_Collection_MatchType rolematchtype,
- const CORBA_char *interfaces,
- const Accessibility_Collection_MatchType interfacematchtype,
- const CORBA_boolean invert,
- CORBA_Environment *ev){
+ const Accessibility_StateSet states,
+ const Accessibility_Collection_MatchType statematchtype,
+ const Accessibility_AttributeSet *attributes,
+ const Accessibility_Collection_MatchType attributematchtype,
+ const Accessibility_RoleSet *roles,
+ const Accessibility_Collection_MatchType rolematchtype,
+ const CORBA_char *interfaces,
+ const Accessibility_Collection_MatchType interfacematchtype,
+ const CORBA_boolean invert,
+ CORBA_Environment *ev){
Accessibility_MatchRule retval = NULL;
SpiMatchrule *matchrule = spi_matchrule_interface_new ();
- MatchRulePrivate *mrp = MATCH_RULE_PRIVATE (matchrule);
- int i;
+ MatchRulePrivate *mrp = get_collection_from_servant (servant)->_mrp;
+ Accessibility_StateSet ss = CORBA_Object_duplicate (states, ev);
+ gint i;
- mrp->states = states;
- mrp->statematchtype = statematchtype;
+ if (mrp != NULL){
+ CORBA_free (mrp->attributes);
+ CORBA_free (mrp->roles);
+ CORBA_free (mrp->interfaces);
+
+ g_free (mrp);
+ }
+
+ get_collection_from_servant (servant)->_mrp = g_new(MatchRulePrivate, 1);
+ mrp = get_collection_from_servant (servant)->_mrp;
-/* attributes */
+ /* states */
+ mrp->states = ss;
+ mrp->statematchtype = statematchtype;
+ /* attributes */
mrp->attributes = CORBA_sequence_CORBA_string__alloc ();
mrp->attributes->_maximum = attributes->_maximum;
mrp->attributes->_length = attributes->_length;
- mrp->attributes->_buffer = CORBA_sequence_CORBA_string_allocbuf (attributes->_length);
+ mrp->attributes->_buffer =
+ CORBA_sequence_CORBA_string_allocbuf (attributes->_length);
for (i = 0; i < mrp->attributes->_length; i++)
- mrp->attributes->_buffer [i]= CORBA_string_dup (attributes->_buffer [i]);
+ mrp->attributes->_buffer [i] =
+ CORBA_string_dup (attributes->_buffer [i]);
CORBA_sequence_set_release (mrp->attributes, TRUE);
mrp->attributematchtype = attributematchtype;
-/* roles */
-
+ /* roles */
mrp->roles = Accessibility_RoleSet__alloc ();
mrp->roles->_maximum = roles->_maximum;
mrp->roles->_length = roles->_length;
for (i = 0; i < roles->_length; i++)
mrp->roles->_buffer [i] = roles->_buffer [i];
-
+
CORBA_sequence_set_release (mrp->roles, TRUE);
mrp->rolematchtype = rolematchtype;
-/* interfaces */
-
+ /* interfaces */
mrp->interfaces = CORBA_string_dup (interfaces);
mrp->interfacematchtype = interfacematchtype;
mrp->invert = invert;
-
+
retval = CORBA_Object_duplicate (BONOBO_OBJREF (matchrule), ev);
return retval;
-
}
static void impl_freeMatchRule (PortableServer_Servant servant,
CORBA_Environment *ev){
SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
- SpiMatchrule *spimatchrule;
+ SpiCollection *spimatchrule;
MatchRulePrivate *mrp;
- spimatchrule = SPI_MATCHRULE (object->gobj);
- mrp = MATCH_RULE_PRIVATE (spimatchrule);;
-
+ spimatchrule = SPI_COLLECTION (object);
+ mrp = spimatchrule->_mrp;
+
CORBA_free (mrp->attributes);
- CORBA_free (mrp->roles);
- CORBA_free (mrp->interfaces);
+ CORBA_free (mrp->roles);
+ CORBA_free (mrp->interfaces);
+
+ g_free (mrp);
+ spimatchrule->_mrp = NULL;
+}
+
+static gboolean
+child_interface_p (Accessibility_Accessible child,
+ gchar *repo_id,
+ CORBA_Environment *ev) {
+
+ CORBA_Object retval;
+
+ retval = Bonobo_Unknown_queryInterface (child, repo_id, ev);
+
+ return (retval != CORBA_OBJECT_NIL)? TRUE : FALSE;
+}
+
+#define child_collection_p(ch,ev) (child_interface_p (ch,"IDL:Accessibility/Collection:1.0", ev))
+
+static gboolean
+match_states_all_p (Accessibility_Accessible child,
+ Accessibility_StateSet set,
+ CORBA_Environment *ev){
+
+ Accessibility_StateSet chs ;
+ Accessibility_StateSeq *seq = Accessibility_StateSet_getStates (set, ev);
+ gint i;
+
+ if (seq->_length == 0 || seq == NULL)
+ return TRUE;
+
+ chs = Accessibility_Accessible_getState (child, ev);
+
+ for (i = 0; i < seq->_length; i++)
+ if (!Accessibility_StateSet_contains (chs, seq->_buffer [i], ev))
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+match_states_any_p (Accessibility_Accessible child,
+ Accessibility_StateSet set,
+ CORBA_Environment *ev){
+
+ Accessibility_StateSet chs;
+ Accessibility_StateSeq *seq = Accessibility_StateSet_getStates (set, ev);
+ gint i;
+
+ if (seq->_length == 0 || seq == NULL)
+ return TRUE;
+
+ chs = Accessibility_Accessible_getState (child, ev);
+
+ for (i = 0; i < seq->_length; i++)
+ if (Accessibility_StateSet_contains (chs, seq->_buffer [i], ev))
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean
+match_states_none_p (Accessibility_Accessible child,
+ Accessibility_StateSet set,
+ CORBA_Environment *ev){
+
+ Accessibility_StateSet chs;
+ Accessibility_StateSeq *seq = Accessibility_StateSet_getStates (set, ev);
+ gint i;
+
+ if (seq->_length == 0)
+ return TRUE;
+ chs = Accessibility_Accessible_getState (child, ev);
- g_free (spimatchrule);
+ for (i = 0; i < seq->_length; i++)
+ if (Accessibility_StateSet_contains (chs, seq->_buffer [i], ev))
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+match_states_lookup (Accessibility_Accessible child,
+ MatchRulePrivate *mrp,
+ CORBA_Environment *ev){
+
+ switch (mrp->statematchtype){
+ case Accessibility_Collection_MATCH_ALL :
+ if (match_states_all_p (child, mrp->states, ev))
+ return TRUE;
+ break;
+
+ case Accessibility_Collection_MATCH_ANY :
+ if (match_states_any_p (child, mrp->states, ev))
+ return TRUE;
+ break;
+
+ case Accessibility_Collection_MATCH_NONE :
+ if (match_states_none_p (child, mrp->states, ev))
+ return TRUE;
+ break;
+
+ default : break;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+match_roles_all_p (Accessibility_Accessible child,
+ Accessibility_RoleSet *roles,
+ CORBA_Environment *ev){
+
+ Accessibility_Role role;
+
+ if (roles->_length > 1)
+ return FALSE;
+ else if (roles->_length == 0 || roles == NULL)
+ return TRUE;
+
+ role = Accessibility_Accessible_getRole (child, ev);
+
+ if (role == roles->_buffer [0])
+ return TRUE;
+ else
+ return FALSE;
+
+}
+
+static gboolean
+match_roles_any_p (Accessibility_Accessible child,
+ Accessibility_RoleSet *roles,
+ CORBA_Environment *ev){
+
+ Accessibility_Role role;
+ int i;
+
+ if (roles->_length == 0 || roles == NULL)
+ return TRUE;
+
+ role = Accessibility_Accessible_getRole (child, ev);
+
+ for (i = 0; i < roles->_length; i++)
+ if (role == roles->_buffer [i])
+ return TRUE;
+ return FALSE;
}
+
+static gboolean
+match_roles_none_p (Accessibility_Accessible child,
+ Accessibility_RoleSet *roles,
+ CORBA_Environment *ev){
+
+ Accessibility_Role role ;
+ int i;
+
+ if (roles->_length == 0 || roles == NULL)
+ return TRUE;
+
+ role = Accessibility_Accessible_getRole (child, ev);
+
+ for (i = 0; i < roles->_length; i++)
+ if (role == roles->_buffer [i])
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+match_roles_lookup (Accessibility_Accessible child,
+ MatchRulePrivate *mrp,
+ CORBA_Environment *ev){
+
+ switch (mrp->rolematchtype){
+ case Accessibility_Collection_MATCH_ALL :
+ if (match_roles_all_p (child, mrp->roles, ev))
+ return TRUE;
+ break;
+
+ case Accessibility_Collection_MATCH_ANY :
+ if (match_roles_any_p (child, mrp->roles, ev))
+ return TRUE;
+ break;
+
+ case Accessibility_Collection_MATCH_NONE :
+ if (match_roles_none_p (child, mrp->roles, ev))
+ return TRUE;
+ break;
+
+ default : break;
+
+ }
+ return FALSE;
+}
+
+#define split_ifaces(ifaces) (g_strsplit (ifaces, ";", 0))
+
+static gboolean
+match_interfaces_all_p (Accessibility_Accessible obj,
+ gchar *interfaces,
+ CORBA_Environment *ev){
+ gchar **ifaces;
+ gint i, length;
+
+ if (interfaces == NULL)
+ return TRUE;
+
+ ifaces = split_ifaces (interfaces);
+ length = g_strv_length (ifaces);
+
+ for (i = 0; i < length; i++)
+ if (!child_interface_p (obj, ifaces [i], ev)){
+ g_free (ifaces);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+match_interfaces_any_p (Accessibility_Accessible obj,
+ gchar *interfaces,
+ CORBA_Environment *ev){
+ gchar **ifaces;
+ gint i, length;
+
+ if (interfaces == NULL)
+ return TRUE;
+
+ ifaces = split_ifaces (interfaces);
+ length = g_strv_length (ifaces);
+
+ for (i = 0; i < length; i++)
+ if (child_interface_p (obj, ifaces [i], ev)){
+ g_free (ifaces);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean
+match_interfaces_none_p (Accessibility_Accessible obj,
+ gchar *interfaces,
+ CORBA_Environment *ev){
+
+ gchar **ifaces = split_ifaces (interfaces);
+ gint i, length = g_strv_length (ifaces);
+
+ if (length == 0)
+ return TRUE;
+
+ for (i = 0; i < length; i++)
+ if (child_interface_p (obj, ifaces [i], ev))
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+match_interfaces_lookup (Accessibility_Accessible child,
+ MatchRulePrivate *mrp,
+ CORBA_Environment *ev){
+
+ switch (mrp->interfacematchtype){
+
+ case Accessibility_Collection_MATCH_ALL :
+ if (match_interfaces_all_p (child, mrp->interfaces, ev))
+ return TRUE;
+ break;
+
+ case Accessibility_Collection_MATCH_ANY :
+ if (match_interfaces_any_p (child, mrp->interfaces, ev))
+ return TRUE;
+ break;
+
+ case Accessibility_Collection_MATCH_NONE :
+ if (match_interfaces_none_p (child, mrp->interfaces, ev))
+ return TRUE;
+ break;
+
+ default : break;
+ }
+
+ return FALSE;
+}
+
+#define split_attributes(attributes) (g_strsplit (attributes, ";", 0))
+
+static gboolean
+match_attributes_all_p (Accessibility_Accessible child,
+ Accessibility_AttributeSet *attributes,
+ CORBA_Environment *ev){
+
+ int i, k;
+ Accessibility_AttributeSet *oa ;
+ gboolean flag = FALSE;
+
+ if (attributes->_length == 0 || attributes == NULL)
+ return TRUE;
+
+ oa = Accessibility_Accessible_getAttributes (child, ev);
+
+ for (i = 0; i < attributes->_length; i++){
+ for (k = 0; k < oa->_length; k++)
+ if (!g_ascii_strcasecmp (oa->_buffer [k],
+ attributes->_buffer [i])){
+ flag = TRUE;
+ break;
+ }
+ else
+ flag = FALSE;
+ if (!flag)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+match_attributes_any_p (Accessibility_Accessible child,
+ Accessibility_AttributeSet *attributes,
+ CORBA_Environment *ev){
+
+ int i, k;
+
+ Accessibility_AttributeSet *oa;
+
+ if (attributes->_length == 0 || attributes == NULL)
+ return TRUE;
+
+ oa = Accessibility_Accessible_getAttributes (child, ev);
+
+ for (i = 0; i < attributes->_length; i++)
+ for (k = 0; k < oa->_length; k++)
+ if (!g_ascii_strcasecmp (oa->_buffer [k],
+ attributes->_buffer[i]))
+ return TRUE;
+ return FALSE;
+}
+
+static gboolean
+match_attributes_none_p (Accessibility_Accessible child,
+ Accessibility_AttributeSet *attributes,
+ CORBA_Environment *ev){
+
+ int i, k;
+ Accessibility_AttributeSet *oa;
+
+ if (attributes->_length == 0 || attributes == NULL)
+ return TRUE;
+
+ oa = Accessibility_Accessible_getAttributes (child, ev);
+
+ for (i = 0; i < attributes->_length; i++){
+ for (k = 0; k < oa->_length; k++)
+ if (!g_ascii_strcasecmp (oa->_buffer [k],
+ attributes->_buffer [i]))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+match_attributes_lookup (Accessibility_Accessible child, MatchRulePrivate *mrp, CORBA_Environment *ev){
+
+ switch (mrp->attributematchtype){
+
+ case Accessibility_Collection_MATCH_ALL :
+ if (match_attributes_all_p (child, mrp->attributes, ev))
+ return TRUE;
+ break;
+
+ case Accessibility_Collection_MATCH_ANY :
+ if (match_attributes_any_p (child, mrp->attributes, ev))
+ return TRUE;
+ break;
+
+ case Accessibility_Collection_MATCH_NONE :
+ if (match_attributes_none_p (child, mrp->attributes, ev))
+ return TRUE;
+ break;
+
+ default : break;
+ }
+ return FALSE;
+}
+
+static gboolean
+traverse_p (Accessibility_Accessible child,
+ const CORBA_boolean traverse,
+ CORBA_Environment *ev){
+
+ if (traverse)
+ return TRUE;
+ else return !child_collection_p (child, ev);
+}
+
+static int
+sort_order_canonical (MatchRulePrivate *mrp, GList *ls,
+ gint kount, gint max,
+ Accessibility_Accessible obj, glong index, gboolean flag,
+ Accessibility_Accessible pobj, CORBA_boolean recurse,
+ CORBA_boolean traverse, CORBA_Environment *ev){
+ gint i = index;
+ glong acount = Accessibility_Accessible__get_childCount (obj, ev);
+ gboolean prev = pobj? TRUE : FALSE;
+
+ for (; i < acount && (max == 0 || kount < max); i++){
+ Accessibility_Accessible child =
+ Accessibility_Accessible_getChildAtIndex (obj, i, ev);
+
+ if (prev && CORBA_Object_is_equivalent (child, pobj, ev)){
+ return kount;
+ }
+
+ if (flag && match_interfaces_lookup (child, mrp, ev)
+ && match_states_lookup (child, mrp, ev)
+ && match_roles_lookup (child, mrp, ev)
+ && match_attributes_lookup (child, mrp, ev)
+ ){
+
+ ls = g_list_append (ls, child);
+ kount++;
+ }
+
+ if (!flag)
+ flag = TRUE;
+
+ if (recurse && traverse_p (child, traverse, ev))
+ kount = sort_order_canonical (mrp, ls, kount,
+ max, child, 0, TRUE,
+ pobj, recurse, traverse, ev);
+ }
+ return kount;
+}
+
+static int
+sort_order_rev_canonical (MatchRulePrivate *mrp, GList *ls,
+ gint kount, gint max,
+ Accessibility_Accessible obj, gboolean flag,
+ Accessibility_Accessible pobj, CORBA_Environment *ev){
+ Accessibility_Accessible nextobj;
+ Accessibility_Accessible parent;
+ glong indexinparent;
+
+ /* This breaks us out of the recursion. */
+ if (obj == CORBA_OBJECT_NIL
+ || CORBA_Object_is_equivalent (obj, pobj, ev))
+ {
+ return kount;
+ }
+
+ /* Add to the list if it matches */
+ if (flag && match_interfaces_lookup (obj, mrp, ev)
+ && match_states_lookup (obj, mrp, ev)
+ && match_roles_lookup (obj, mrp, ev)
+ && match_attributes_lookup (obj, mrp, ev))
+ {
+ ls = g_list_append (ls, obj);
+ kount++;
+ }
+
+ if(!flag) flag = TRUE;
+
+ /* Get the current nodes index in it's parent and the parent object. */
+ indexinparent = Accessibility_Accessible_getIndexInParent (obj, ev);
+ parent = Accessibility_Accessible__get_parent (obj, ev);
+
+ if(indexinparent > 0)
+ {
+ /* there are still some siblings to visit so get the previous sibling
+ and get it's last descendant.
+ First, get the previous sibling */
+ nextobj = Accessibility_Accessible_getChildAtIndex (parent,
+ indexinparent-1,
+ ev);
+
+ /* Now, drill down the right side to the last descendant */
+ while(Accessibility_Accessible__get_childCount (nextobj, ev) > 0)
+ {
+ nextobj = Accessibility_Accessible_getChildAtIndex (nextobj,
+ Accessibility_Accessible__get_childCount (nextobj, ev)-1, ev);
+
+ }
+ /* recurse with the last descendant */
+ kount = sort_order_rev_canonical (mrp, ls, kount, max,
+ nextobj, TRUE, pobj, ev);
+ }
+ else
+ {
+ /* no more siblings so next node must be the parent */
+ kount = sort_order_rev_canonical (mrp, ls, kount, max,
+ parent, TRUE, pobj, ev);
+
+ }
+ return kount;
+}
+
+static int
+query_exec (MatchRulePrivate *mrp, Accessibility_Collection_SortOrder sortby,
+ GList *ls, gint kount, gint max,
+ Accessibility_Accessible obj, glong index,
+ gboolean flag,
+ Accessibility_Accessible pobj,
+ CORBA_boolean recurse, CORBA_boolean traverse,
+ CORBA_Environment *ev){
+
+ switch (sortby) {
+ case Accessibility_Collection_SORT_ORDER_CANONICAL :
+ kount = sort_order_canonical(mrp, ls, 0, max, obj, index, flag,
+ pobj, recurse, traverse, ev);
+ break;
+ case Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL :
+ kount = sort_order_canonical(mrp, ls, 0, max, obj, index, flag,
+ pobj, recurse, traverse, ev);
+ break;
+ default:
+ kount = 0;
+ g_warning ("Sort method not implemented yet");
+ break;
+ }
+
+ return kount;
+
+}
+
+
+static Accessibility_AccessibleSet *
+_accessible_list_to_set (GList *ls, gint kount){
+ Accessibility_AccessibleSet *retval;
+ gint i;
+
+ retval = Accessibility_AccessibleSet__alloc ();
+ retval->_maximum = kount;
+ retval->_length = kount;
+ retval->_buffer = Accessibility_AccessibleSet_allocbuf (kount);
+
+ for (i=0; i < kount; i++){
+ retval->_buffer [i] = ls->data;
+ ls = g_list_next (ls);
+ }
+
+ CORBA_sequence_set_release (retval, TRUE);
+
+ return retval;
+}
+
+static Accessibility_AccessibleSet *
+getMatchesFrom (PortableServer_Servant servant,
+ const Accessibility_Accessible current_object,
+ const Accessibility_MatchRule rule,
+ const Accessibility_Collection_SortOrder sortby,
+ const CORBA_boolean isrestrict,
+ CORBA_long count,
+ const CORBA_boolean traverse,
+ CORBA_Environment *ev){
+
+ GList *ls = NULL;
+ Accessibility_Accessible parent;
+ MatchRulePrivate *mrp;
+ glong index =
+ Accessibility_Accessible_getIndexInParent (current_object, ev);
+ gint kount = 0;
+
+ ls = g_list_append (ls, current_object);
+ mrp = get_collection_from_servant (servant)->_mrp;;
+
+ if (!isrestrict){
+ parent = Accessibility_Accessible__get_parent (current_object, ev);
+ kount = query_exec (mrp, sortby, ls, 0, count, parent, index,
+ FALSE, CORBA_OBJECT_NIL, TRUE, traverse, ev);
+ }
+ else
+ kount = query_exec (mrp, sortby, ls, 0, count,
+ current_object, 0, FALSE, CORBA_OBJECT_NIL,
+ TRUE, traverse, ev);
+
+ ls = g_list_next (ls);
+
+ if (sortby == Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
+ ls = g_list_reverse (ls);
+
+ return _accessible_list_to_set (ls, kount);
+}
+
+/*
+ inorder traversal from a given object in the hierarchy
+*/
+
+static int
+inorder (Accessibility_Accessible collection, MatchRulePrivate *mrp,
+ GList *ls, gint kount, gint max,
+ Accessibility_Accessible obj,
+ gboolean flag,
+ Accessibility_Accessible pobj,
+ CORBA_boolean traverse,
+ CORBA_Environment *ev){
+
+ int i = 0;
+
+ /* First, look through the children recursively. */
+ kount = sort_order_canonical (mrp, ls, kount, max, obj, 0, TRUE,
+ CORBA_OBJECT_NIL, TRUE, TRUE, ev);
+
+ /* Next, we look through the right subtree */
+ while ((max == 0 || kount < max)
+ && ! CORBA_Object_is_equivalent (obj, collection, ev))
+ {
+ Accessibility_Accessible parent =
+ Accessibility_Accessible__get_parent (obj, ev);
+ i = Accessibility_Accessible_getIndexInParent (obj, ev);
+ kount = sort_order_canonical (mrp, ls, kount, max, parent,
+ i+1, TRUE, FALSE, TRUE, TRUE, ev);
+ obj = parent;
+ }
+
+ if (kount < max)
+ {
+ kount = sort_order_canonical (mrp, ls, kount, max,
+ obj, i + 1, TRUE, FALSE,
+ TRUE, TRUE, ev);
+ }
+
+ return kount;
+}
+
+/*
+ GetMatchesInOrder: get matches from a given object in an inorder traversal.
+*/
+
+static Accessibility_AccessibleSet *
+getMatchesInOrder (PortableServer_Servant servant,
+ const Accessibility_Accessible current_object,
+ const Accessibility_MatchRule rule,
+ const Accessibility_Collection_SortOrder sortby,
+ const CORBA_boolean recurse,
+ CORBA_long count,
+ const CORBA_boolean traverse,
+ CORBA_Environment *ev){
+ GList *ls = NULL;
+ AtkObject *aobj;
+ Accessibility_Accessible obj;
+ MatchRulePrivate *mrp;
+ gint kount = 0;
+
+ ls = g_list_append (ls, current_object);
+ mrp = get_collection_from_servant (servant)->_mrp;
+
+ aobj = get_atkobject_from_servant (servant);
+ obj = spi_accessible_new_return (aobj, FALSE, ev);
+
+ kount = inorder (obj, mrp, ls, 0, count,
+ current_object, TRUE, CORBA_OBJECT_NIL, traverse, ev);
+
+ ls = g_list_next (ls);
+
+ if (sortby == Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
+ ls = g_list_reverse (ls);
+
+ return _accessible_list_to_set (ls, kount);
+}
+
+/*
+ GetMatchesInOrder: get matches from a given object in an inorder traversal.
+*/
+
+static Accessibility_AccessibleSet *
+getMatchesInBackOrder (PortableServer_Servant servant,
+ const Accessibility_Accessible current_object,
+ const Accessibility_MatchRule rule,
+ const Accessibility_Collection_SortOrder sortby,
+ CORBA_long count,
+ CORBA_Environment *ev){
+ GList *ls = NULL;
+ AtkObject *aobj;
+ Accessibility_Accessible collection;
+ MatchRulePrivate *mrp;
+ gint kount = 0;
+
+ ls = g_list_append (ls, current_object);
+ mrp = get_collection_from_servant (servant)->_mrp;
+
+ aobj = get_atkobject_from_servant (servant);
+ collection = spi_accessible_new_return (aobj, FALSE, ev);
+
+ kount = sort_order_rev_canonical (mrp, ls, 0, count, current_object,
+ FALSE, collection, ev);
+
+ ls = g_list_next (ls);
+
+ if (sortby == Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
+ ls = g_list_reverse (ls);
+
+ return _accessible_list_to_set (ls, kount);
+}
+
+
+static Accessibility_AccessibleSet *
+getMatchesTo (PortableServer_Servant servant,
+ const Accessibility_Accessible current_object,
+ const Accessibility_MatchRule rule,
+ const Accessibility_Collection_SortOrder sortby,
+ const CORBA_boolean recurse,
+ const CORBA_boolean isrestrict,
+ CORBA_long count,
+ const CORBA_boolean traverse,
+ CORBA_Environment *ev){
+
+ GList *ls = NULL;
+ AtkObject *aobj;
+ Accessibility_Accessible obj;
+ MatchRulePrivate *mrp;
+ gint kount = 0;
+
+ ls = g_list_append (ls, current_object);
+ mrp = get_collection_from_servant (servant)->_mrp;
+
+ if (recurse){
+ obj = Accessibility_Accessible__get_parent (current_object, ev);
+ kount = query_exec (mrp, sortby, ls, 0, count,
+ obj, 0, TRUE, current_object, TRUE, traverse, ev);
+ }
+ else{
+ aobj = get_atkobject_from_servant (servant);
+ obj = spi_accessible_new_return (aobj, FALSE, ev);
+ kount = query_exec (mrp, sortby, ls, 0, count,
+ obj, 0, TRUE, current_object, TRUE, traverse, ev);
+
+ }
+
+ ls = g_list_next (ls);
+
+ if (sortby != Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
+ ls = g_list_reverse (ls);
+
+ return _accessible_list_to_set (ls, kount);
+
+}
+
+static Accessibility_AccessibleSet *
+impl_getMatchesFrom (PortableServer_Servant servant,
+ const Accessibility_Accessible current_object,
+ const Accessibility_MatchRule rule,
+ const Accessibility_Collection_SortOrder sortby,
+ const Accessibility_Collection_TreeTraversalType tree,
+ CORBA_long count,
+ const CORBA_boolean traverse,
+ CORBA_Environment *ev){
+
+ switch (tree){
+ case Accessibility_Collection_TREE_RESTRICT_CHILDREN :
+ return getMatchesFrom (servant, current_object,
+ rule, sortby, TRUE, count, traverse, ev);
+ break;
+ case Accessibility_Collection_TREE_RESTRICT_SIBLING :
+ return getMatchesFrom (servant, current_object,
+ rule, sortby, FALSE, count, traverse, ev);
+ break;
+ case Accessibility_Collection_TREE_INORDER :
+ return getMatchesInOrder (servant, current_object,
+ rule, sortby, TRUE, count, traverse, ev);
+ break;
+ default : return CORBA_OBJECT_NIL;
+ }
+}
+
+static Accessibility_AccessibleSet *
+impl_getMatchesTo (PortableServer_Servant servant,
+ const Accessibility_Accessible current_object,
+ const Accessibility_MatchRule rule,
+ const Accessibility_Collection_SortOrder sortby,
+ const Accessibility_Collection_TreeTraversalType tree,
+ const CORBA_boolean recurse,
+ CORBA_long count,
+ const CORBA_boolean traverse,
+ CORBA_Environment *ev){
+
+ switch (tree){
+ case Accessibility_Collection_TREE_RESTRICT_CHILDREN :
+ return getMatchesTo (servant, current_object,
+ rule, sortby, recurse, TRUE, count, traverse, ev);
+ break;
+ case Accessibility_Collection_TREE_RESTRICT_SIBLING :
+ return getMatchesTo (servant, current_object,
+ rule, sortby, recurse, FALSE, count, traverse, ev);
+ break;
+ case Accessibility_Collection_TREE_INORDER :
+ return getMatchesInBackOrder (servant, current_object,
+ rule, sortby, count, ev);
+ break;
+ default : return CORBA_OBJECT_NIL;
+ }
+}
+
+static Accessibility_AccessibleSet *
+impl_getMatches (PortableServer_Servant servant,
+ const Accessibility_MatchRule rule,
+ const Accessibility_Collection_SortOrder sortby,
+ CORBA_long count,
+ const CORBA_boolean traverse,
+ CORBA_Environment *ev){
+ GList *ls = NULL;
+ AtkObject *aobj = get_atkobject_from_servant (servant);
+ Accessibility_Accessible obj;
+ MatchRulePrivate *mrp;
+ gint kount = 0;
+
+ obj = spi_accessible_new_return (aobj, FALSE, ev);
+ ls = g_list_prepend (ls, obj);
+ mrp = get_collection_from_servant (servant)->_mrp;
+
+ kount = query_exec (mrp, sortby, ls, 0, count,
+ obj, 0, TRUE, CORBA_OBJECT_NIL, TRUE, traverse, ev);
+
+ ls = g_list_next (ls);
+
+ if (sortby == Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
+ ls = g_list_reverse (ls);
+
+ return _accessible_list_to_set (ls, kount);
+}
+
static void
spi_collection_class_init (SpiCollectionClass *klass)
{
POA_Accessibility_Collection__epv *epv = &klass->epv;
- /* epv->isAncestorOf = impl_isAncestorOf; */
+ /*
+ epv->isAncestorOf = impl_isAncestorOf;
+ */
+
+ epv->createMatchRule = impl_createMatchRule;
+ epv->freeMatchRule = impl_freeMatchRule;
+ epv->getMatches = impl_getMatches;
+ epv->getMatchesTo = impl_getMatchesTo;
+ epv->getMatchesFrom = impl_getMatchesFrom;
- epv->createMatchRule = impl_createMatchRule;
- epv->freeMatchRule = impl_freeMatchRule;
-
- /*
- epv->getChildren = impl_getChildren;
- epv->getPreviousChildren = impl_getPreviousChildren;
- epv->getNextChildren = impl_getNextChildren;
- epv->getActiveDescendant = impl_getActiveDescendant;
- */
- g_type_class_add_private (klass, sizeof (MatchRulePrivate));
+ /*
+ epv->getActiveDescendant = impl_getActiveDescendant;
+ */
+
}
static void
spi_collection_init (SpiCollection *collection)
{
+
+ /* collection->_mrp = g_new (MatchRulePrivate, 1); */
+
}
BONOBO_TYPE_FUNC_FULL (SpiCollection,