2007-12-03 Li Yuan <li.yuan@sun.com>
[platform/core/uifw/at-spi2-atk.git] / libspi / collection.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2007 IBM Corp.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /* collection.c: implements the Collection interface */
24
25 #include <config.h>
26 #include <glib.h>
27 #include <stdio.h>
28 #include <bonobo/bonobo-exception.h>
29 #include <libspi/accessible.h>
30 #include <libspi/collection.h>
31 #include <libspi/matchrule.h> 
32 #include <libspi/stateset.h>
33 #include <libspi/spi-private.h>
34
35 SpiCollection *
36 spi_collection_interface_new (AtkObject *obj)
37 {
38
39      SpiCollection *new_collection = g_object_new (SPI_COLLECTION_TYPE, NULL);
40      spi_base_construct (SPI_BASE (new_collection), G_OBJECT (obj));
41
42      return  new_collection;
43
44 }
45
46
47 static AtkObject *
48 get_atkobject_from_servant (PortableServer_Servant servant){
49
50      SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
51
52   g_return_val_if_fail (object, NULL);
53   g_return_val_if_fail (ATK_IS_OBJECT (object->gobj), NULL);
54   
55   return ATK_OBJECT (object->gobj);
56 }
57
58 static SpiCollection *
59 get_collection_from_servant (PortableServer_Servant servant)
60 {
61      SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
62      
63      g_return_val_if_fail (object, NULL);
64      g_return_val_if_fail (IS_COLLECTION (object), NULL);
65
66      return SPI_COLLECTION (object);
67                                 
68 }
69
70
71 static Accessibility_MatchRule 
72 impl_createMatchRule (PortableServer_Servant servant,
73                       const Accessibility_StateSet states,
74                       const Accessibility_Collection_MatchType statematchtype,
75                       const Accessibility_AttributeSet *attributes,
76                       const Accessibility_Collection_MatchType attributematchtype,
77                       const Accessibility_RoleSet *roles,
78                       const Accessibility_Collection_MatchType rolematchtype,
79                       const CORBA_char *interfaces,
80                       const Accessibility_Collection_MatchType interfacematchtype,
81                       const CORBA_boolean invert,
82                       CORBA_Environment *ev){
83
84      Accessibility_MatchRule  retval = NULL;
85
86      SpiMatchrule *matchrule = spi_matchrule_interface_new ();
87      MatchRulePrivate *mrp   = get_collection_from_servant (servant)->_mrp;     
88      Accessibility_StateSet ss = CORBA_Object_duplicate (states, ev);
89      gint i;
90
91
92      if (mrp != NULL){
93        CORBA_free (mrp->attributes);
94        CORBA_free (mrp->roles);
95        CORBA_free (mrp->interfaces);
96
97        g_free (mrp);
98      }
99      
100      get_collection_from_servant (servant)->_mrp  = g_new (MatchRulePrivate, 1);
101      mrp   = get_collection_from_servant (servant)->_mrp;
102
103      /* states */
104
105      mrp->states  = ss;
106      mrp->statematchtype = statematchtype;
107
108      /* attributes */
109
110      mrp->attributes = CORBA_sequence_CORBA_string__alloc ();
111      mrp->attributes->_maximum = attributes->_maximum;
112      mrp->attributes->_length = attributes->_length;
113      mrp->attributes->_buffer = CORBA_sequence_CORBA_string_allocbuf (attributes->_length);
114
115      for (i = 0; i < mrp->attributes->_length; i++)
116           mrp->attributes->_buffer [i]= CORBA_string_dup (attributes->_buffer [i]);
117     
118      CORBA_sequence_set_release (mrp->attributes, TRUE);
119      mrp->attributematchtype = attributematchtype;
120
121      /* roles */
122
123      mrp->roles = Accessibility_RoleSet__alloc ();
124      mrp->roles->_maximum = roles->_maximum;
125      mrp->roles->_length = roles->_length;
126      mrp->roles->_buffer = Accessibility_RoleSet_allocbuf (roles->_length);
127
128      for (i = 0; i < roles->_length; i++)
129           mrp->roles->_buffer [i] = roles->_buffer [i];
130      
131      CORBA_sequence_set_release (mrp->roles, TRUE);
132      mrp->rolematchtype = rolematchtype;
133
134      /* interfaces */
135      
136      mrp->interfaces = CORBA_string_dup (interfaces);
137      mrp->interfacematchtype = interfacematchtype;
138
139      mrp->invert = invert;
140
141      retval = CORBA_Object_duplicate (BONOBO_OBJREF (matchrule), ev);
142
143      return retval;
144
145 }
146
147 static void impl_freeMatchRule (PortableServer_Servant servant,
148                                 Accessibility_MatchRule matchrule,     
149                                 CORBA_Environment *ev){
150
151      SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
152      SpiCollection *spimatchrule;
153
154      MatchRulePrivate *mrp;  
155
156      spimatchrule = SPI_COLLECTION (object);
157      mrp =  spimatchrule->_mrp;
158      
159      CORBA_free (mrp->attributes);
160      CORBA_free (mrp->roles);
161      CORBA_free (mrp->interfaces);
162
163      g_free (mrp);
164
165 }
166
167
168
169 static gboolean
170 child_interface_p (Accessibility_Accessible child, gchar *repo_id, CORBA_Environment *ev) {
171           
172      CORBA_Object retval;
173      
174      retval = Bonobo_Unknown_queryInterface (child, repo_id, ev);
175      
176      return (retval != CORBA_OBJECT_NIL)? TRUE : FALSE;
177
178 }
179
180 #define child_collection_p(ch,ev) (child_interface_p (ch,"IDL:Accessibility/Collection:1.0", ev))
181
182 static gboolean
183 match_states_all_p (Accessibility_Accessible child, Accessibility_StateSet set,  CORBA_Environment *ev){
184      
185
186      Accessibility_StateSet chs  ;
187      Accessibility_StateSeq *seq = Accessibility_StateSet_getStates (set, ev); 
188      gint i;
189
190      if (seq->_length == 0 || seq == NULL)
191           return TRUE;
192
193      chs = Accessibility_Accessible_getState (child, ev);
194      
195      
196      for (i = 0; i < seq->_length; i++)
197           if (!Accessibility_StateSet_contains (chs, seq->_buffer [i], ev))
198                return FALSE;
199    
200      return TRUE;
201           
202 }
203
204 static gboolean
205 match_states_any_p  (Accessibility_Accessible child, Accessibility_StateSet set,  CORBA_Environment *ev){
206      
207      Accessibility_StateSet chs; 
208      Accessibility_StateSeq *seq = Accessibility_StateSet_getStates (set, ev);
209      gint i;
210
211      if (seq->_length == 0 || seq == NULL)
212           return TRUE;
213
214      chs = Accessibility_Accessible_getState (child, ev);
215
216      for (i = 0; i < seq->_length; i++)
217           if (Accessibility_StateSet_contains (chs, seq->_buffer [i], ev))
218                return TRUE;
219
220      return FALSE;
221
222 }
223
224 static gboolean
225 match_states_none_p (Accessibility_Accessible child, Accessibility_StateSet set,  CORBA_Environment *ev){
226      
227      Accessibility_StateSet chs; 
228      Accessibility_StateSeq *seq = Accessibility_StateSet_getStates (set, ev);
229      gint i;
230
231      if (seq->_length == 0)
232           return TRUE; 
233      chs = Accessibility_Accessible_getState (child, ev);
234      
235      for (i = 0; i < seq->_length; i++)
236           if (Accessibility_StateSet_contains (chs, seq->_buffer [i], ev))
237                return FALSE;
238
239      return TRUE;
240
241 }
242
243 static gboolean
244 match_states_lookup (Accessibility_Accessible child,  MatchRulePrivate *mrp, CORBA_Environment *ev){
245
246      switch (mrp->statematchtype){
247      case Accessibility_Collection_MATCH_ALL : 
248           if (match_states_all_p (child, mrp->states, ev))
249                return TRUE;
250           break;
251           
252      case  Accessibility_Collection_MATCH_ANY :
253           if (match_states_any_p (child, mrp->states, ev))
254                return TRUE;
255           break;
256           
257      case  Accessibility_Collection_MATCH_NONE :
258           if (match_states_none_p (child, mrp->states, ev))
259                return TRUE;
260           break;
261
262       default : break;    
263      }
264
265      return FALSE;    
266
267 }
268
269 static gboolean
270 match_roles_all_p (Accessibility_Accessible child, Accessibility_RoleSet *roles,  CORBA_Environment *ev){
271
272    Accessibility_Role role; 
273
274      if (roles->_length > 1) 
275           return FALSE;
276      else if (roles->_length == 0 || roles == NULL)
277           return TRUE;
278
279      role  = Accessibility_Accessible_getRole (child, ev);
280
281      if (role  == roles->_buffer [0])
282           return TRUE;
283      else 
284           return FALSE;
285     
286 }
287
288
289 static gboolean
290 match_roles_any_p (Accessibility_Accessible child, Accessibility_RoleSet *roles, CORBA_Environment *ev){
291
292      Accessibility_Role role; 
293      int i;
294
295      if (roles->_length == 0 || roles == NULL)
296           return TRUE;
297
298      role =  Accessibility_Accessible_getRole (child, ev);
299
300      for (i = 0; i < roles->_length; i++)
301           if (role  == roles->_buffer [i])
302                return TRUE;
303
304      return FALSE;
305
306 }
307
308 static gboolean
309 match_roles_none_p (Accessibility_Accessible child, Accessibility_RoleSet *roles,  CORBA_Environment *ev){
310
311   Accessibility_Role role ; 
312      int i;
313
314      if (roles->_length == 0 || roles == NULL)
315           return TRUE;
316
317      role =  Accessibility_Accessible_getRole (child, ev);
318
319      for (i = 0; i < roles->_length; i++)
320           if (role == roles->_buffer [i])
321                return FALSE;
322
323      return TRUE;
324      
325 }
326
327
328 static gboolean
329 match_roles_lookup (Accessibility_Accessible child,  MatchRulePrivate *mrp, CORBA_Environment *ev){
330
331       switch (mrp->rolematchtype){
332          case Accessibility_Collection_MATCH_ALL : 
333               if (match_roles_all_p (child, mrp->roles, ev))
334                    return TRUE;
335               break;
336
337          case  Accessibility_Collection_MATCH_ANY :
338               if (match_roles_any_p (child, mrp->roles, ev))
339                    return TRUE;
340               break;
341
342          case  Accessibility_Collection_MATCH_NONE :
343               if (match_roles_none_p (child, mrp->roles, ev))
344                    return TRUE;
345               break;
346
347       default : break;
348  
349          }
350
351       return FALSE;
352
353 }
354
355
356 #define split_ifaces(ifaces) (g_strsplit (ifaces, ";", 0))
357
358 static gboolean
359 match_interfaces_all_p (Accessibility_Accessible obj, gchar *interfaces, CORBA_Environment *ev){
360      gchar **ifaces; 
361      gint i, length; 
362
363      if (interfaces == NULL)
364        return TRUE;
365
366      ifaces = split_ifaces (interfaces);
367      length = g_strv_length (ifaces);
368
369      for (i = 0; i < length; i++)
370        if (!child_interface_p (obj, ifaces [i], ev)){
371             g_free (ifaces);
372                return FALSE;
373        }
374      return TRUE;
375      
376
377 }
378
379 static gboolean
380 match_interfaces_any_p (Accessibility_Accessible obj, gchar *interfaces, CORBA_Environment *ev){
381      gchar **ifaces; 
382      gint i, length; 
383
384      if (interfaces == NULL)
385        return TRUE;
386
387      ifaces = split_ifaces (interfaces);
388      length = g_strv_length (ifaces);
389
390      for (i = 0; i < length; i++)
391        if (child_interface_p (obj, ifaces [i], ev)){
392                 g_free (ifaces);
393                 return TRUE;
394        }
395      
396      return FALSE;
397 }
398
399 static gboolean
400 match_interfaces_none_p (Accessibility_Accessible obj, gchar *interfaces, CORBA_Environment *ev){
401
402  gchar **ifaces = split_ifaces (interfaces);
403      gint i, length = g_strv_length (ifaces);
404
405      if (length == 0)
406           return TRUE;
407
408      for (i = 0; i < length; i++)
409            if (child_interface_p (obj, ifaces [i], ev))
410                 return FALSE;
411      
412      return TRUE;
413    
414
415 }
416
417 static gboolean
418 match_interfaces_lookup (Accessibility_Accessible child, MatchRulePrivate *mrp, CORBA_Environment *ev){
419
420      switch (mrp->interfacematchtype){
421
422      case Accessibility_Collection_MATCH_ALL : 
423           if (match_interfaces_all_p (child, mrp->interfaces, ev))
424                return TRUE;
425           break;
426           
427      case  Accessibility_Collection_MATCH_ANY :
428           if (match_interfaces_any_p (child, mrp->interfaces, ev))
429                return TRUE;
430           break;
431           
432      case  Accessibility_Collection_MATCH_NONE :
433           if (match_interfaces_none_p (child, mrp->interfaces, ev))
434                return TRUE;
435           break;
436
437       default : break;    
438      }
439
440      return FALSE;     
441 }
442
443 #define split_attributes(attributes) (g_strsplit (attributes, ";", 0))
444
445 static gboolean 
446 match_attributes_all_p (Accessibility_Accessible child, Accessibility_AttributeSet  *attributes, CORBA_Environment *ev){
447
448      int i, k;
449      Accessibility_AttributeSet *oa ;
450      gboolean flag = FALSE;
451
452      if (attributes->_length == 0 || attributes == NULL)
453           return TRUE;
454      
455      oa =  Accessibility_Accessible_getAttributes (child, ev);
456
457      for (i = 0; i < attributes->_length; i++){
458           for (k = 0; k < oa->_length; k++)
459                if (!g_ascii_strcasecmp (oa->_buffer [k], attributes->_buffer [i]))
460                     flag = TRUE;
461                else
462                     flag = FALSE;
463           if (!flag) 
464                return FALSE; 
465      }
466      return TRUE;
467 }
468
469 static gboolean 
470 match_attributes_any_p (Accessibility_Accessible child, Accessibility_AttributeSet  *attributes, CORBA_Environment *ev){
471
472      int i, k;
473
474      Accessibility_AttributeSet *oa;
475
476      if (attributes->_length == 0 || attributes == NULL)
477           return TRUE;
478
479      oa =  Accessibility_Accessible_getAttributes (child, ev);
480
481      for (i = 0; i < attributes->_length; i++)
482           for (k = 0; k < oa->_length; k++)
483                if (!g_ascii_strcasecmp (oa->_buffer [k], attributes->_buffer[i]))
484                     return TRUE;
485      return FALSE;
486 }
487
488
489
490 static gboolean 
491 match_attributes_none_p (Accessibility_Accessible child, Accessibility_AttributeSet  *attributes, CORBA_Environment *ev){
492
493      int i, k;
494      Accessibility_AttributeSet *oa;
495      gboolean flag = FALSE;
496      
497      if (attributes->_length == 0 || attributes == NULL)
498           return TRUE;
499
500      oa =  Accessibility_Accessible_getAttributes (child, ev);
501
502      for (i = 0; i < attributes->_length; i++){
503           for (k = 0; k < oa->_length; k++)
504                if (!g_ascii_strcasecmp (oa->_buffer [k], attributes->_buffer [i]))
505                     flag = FALSE;
506                else
507                     flag = TRUE;
508           if (flag) 
509                return TRUE; 
510      }
511      return FALSE;
512 }
513
514
515
516
517 static gboolean
518 match_attributes_lookup (Accessibility_Accessible child, MatchRulePrivate *mrp, CORBA_Environment *ev){
519
520      switch (mrp->attributematchtype){
521
522           case Accessibility_Collection_MATCH_ALL : 
523           if (match_attributes_all_p (child, mrp->attributes, ev))
524                return TRUE;
525           break;
526           
527      case  Accessibility_Collection_MATCH_ANY :
528           if (match_attributes_any_p (child, mrp->attributes, ev))
529                return TRUE;
530           break;
531           
532      case  Accessibility_Collection_MATCH_NONE :
533           if (match_attributes_none_p (child, mrp->attributes, ev))
534                return TRUE;
535           break;
536
537       default : break;    
538      }
539
540      return FALSE;   
541
542
543
544 }
545
546 static gboolean
547 traverse_p (Accessibility_Accessible child, 
548             const CORBA_boolean traverse,
549             CORBA_Environment *ev){
550
551   if (traverse)
552     return TRUE;
553   else return !child_collection_p (child, ev);
554         
555 }
556
557 static int 
558 sort_order_canonical (MatchRulePrivate *mrp, GList *ls,                       
559                       gint kount, gint max,
560                       Accessibility_Accessible obj, glong index, gboolean flag, 
561                       Accessibility_Accessible pobj, CORBA_boolean recurse, 
562                       CORBA_boolean traverse, CORBA_Environment *ev){
563
564      gint i = index;
565      glong acount  = Accessibility_Accessible__get_childCount (obj, ev);
566      gboolean prev = pobj? TRUE : FALSE;
567    
568      for (; i < acount && (max == 0 || kount < max); i++){
569           Accessibility_Accessible child = Accessibility_Accessible_getChildAtIndex (obj, i, ev);
570
571                   
572           if (prev && CORBA_Object_is_equivalent (child, pobj, ev)){
573
574             return kount;           
575
576           }
577          
578           if (flag  && match_interfaces_lookup (child, mrp, ev) && match_states_lookup (child, mrp, ev)     
579                     && match_roles_lookup (child, mrp, ev)  
580                     && match_attributes_lookup (child, mrp, ev)
581                     ){
582            
583             ls = g_list_append (ls, child);
584             
585             kount++;
586           }
587             
588           if (!flag)
589                flag = TRUE;
590
591          
592           if (recurse && traverse_p (child, traverse, ev))
593             kount = sort_order_canonical (mrp, ls,  kount, max, child, 0, TRUE, pobj, recurse, traverse, ev);  
594      }
595      return kount;
596
597
598 static int
599 query_exec (MatchRulePrivate *mrp,  Accessibility_Collection_SortOrder sortby, 
600             GList *ls, gint kount, gint max, 
601             Accessibility_Accessible obj, glong index, 
602             gboolean flag, 
603             Accessibility_Accessible pobj,
604             CORBA_boolean recurse, CORBA_boolean traverse,
605             CORBA_Environment *ev){
606      switch (sortby) {
607      case Accessibility_Collection_SORT_ORDER_CANONICAL :  kount = sort_order_canonical  (mrp, ls, 0, max, obj, index, flag, pobj, recurse, traverse, ev); 
608        break;
609      case Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL :
610        kount = sort_order_canonical  (mrp, ls, 0, max, obj, index, flag, pobj, recurse, traverse, ev);    
611            break;
612        
613      default: kount = 0; g_warning ("Sort method not implemented yet"); break; 
614      }
615      
616      return kount;
617
618 }
619
620
621 static Accessibility_AccessibleSet *
622 _accessible_list_to_set (GList *ls, gint kount){
623     Accessibility_AccessibleSet *retval;
624     gint i;
625    
626      retval = Accessibility_AccessibleSet__alloc ();
627      retval->_maximum = kount; 
628      retval->_length = kount; 
629      retval->_buffer = Accessibility_AccessibleSet_allocbuf (kount);
630
631      for (i=0; i < kount; i++){
632        retval->_buffer [i] = ls->data;
633        ls = g_list_next (ls);
634      }
635      
636      CORBA_sequence_set_release (retval, TRUE);
637      
638      return retval;
639 }
640
641 static Accessibility_AccessibleSet *
642 impl_getMatchesFrom (PortableServer_Servant servant,
643                       const Accessibility_Accessible current_object,
644                       const Accessibility_MatchRule rule,
645                       const Accessibility_Collection_SortOrder sortby,
646                       const CORBA_boolean isrestrict,
647                       CORBA_long  count,
648                       const CORBA_boolean traverse,
649                       CORBA_Environment *ev){
650     
651      GList *ls = NULL;
652      Accessibility_Accessible parent; 
653      MatchRulePrivate *mrp;
654      glong index = Accessibility_Accessible_getIndexInParent (current_object, ev);
655      gint kount = 0;
656
657      ls = g_list_append (ls, current_object);
658      mrp =  get_collection_from_servant (servant)->_mrp;;
659           
660      if (!isrestrict){
661           parent = Accessibility_Accessible__get_parent (current_object, ev);
662           kount = query_exec (mrp,  sortby, ls, 0, count, parent, index, FALSE, CORBA_OBJECT_NIL, TRUE, traverse, ev);
663
664      }
665      else 
666           kount = query_exec (mrp,  sortby, ls, 0,count,  current_object, 0, FALSE, CORBA_OBJECT_NIL, TRUE, traverse, ev);
667
668
669      ls = g_list_next (ls); 
670
671      if (sortby == Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
672        ls = g_list_reverse (ls);
673  
674      return  _accessible_list_to_set (ls, kount);
675 }
676
677
678 static Accessibility_AccessibleSet *
679 impl_getMatchesTo (PortableServer_Servant servant,
680                       const Accessibility_Accessible current_object,
681                       const Accessibility_MatchRule rule,
682                       const Accessibility_Collection_SortOrder sortby,
683                       const CORBA_boolean recurse, 
684                       CORBA_long  count,
685                       const CORBA_boolean traverse,
686                       CORBA_Environment *ev){
687
688
689   GList *ls = NULL;
690   AtkObject *aobj;
691   Accessibility_Accessible obj;
692   MatchRulePrivate *mrp;
693    gint kount = 0;
694
695
696   ls = g_list_append (ls, current_object); 
697   mrp =  get_collection_from_servant (servant)->_mrp;
698   
699   
700   if (recurse){
701     obj = Accessibility_Accessible__get_parent (current_object, ev);
702     kount =  query_exec (mrp,  sortby, ls, 0, count,  obj, 0, TRUE, current_object, TRUE, traverse, ev);
703   }
704   else{
705     aobj = get_atkobject_from_servant (servant);
706     obj = spi_accessible_new_return (aobj, FALSE, ev);
707     kount = query_exec (mrp,  sortby, ls, 0, count, obj, 0, TRUE, current_object, TRUE, traverse, ev); 
708
709   }
710
711   ls = g_list_next (ls); 
712    
713   if (sortby == Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
714     ls = g_list_reverse (ls);
715  
716   return  _accessible_list_to_set (ls, kount);
717   
718 }
719
720
721
722 static Accessibility_AccessibleSet *
723 impl_getMatches (PortableServer_Servant servant,
724                  const Accessibility_MatchRule rule,
725                  const Accessibility_Collection_SortOrder sortby,
726                  CORBA_long  count,
727                  const CORBA_boolean traverse,
728                  CORBA_Environment *ev){
729      GList *ls = NULL;
730      AtkObject *aobj = get_atkobject_from_servant (servant);
731      Accessibility_Accessible obj;
732      MatchRulePrivate *mrp;
733      gint kount = 0;
734     
735      obj = spi_accessible_new_return (aobj, FALSE, ev);
736      ls = g_list_prepend (ls, obj); 
737      mrp =  get_collection_from_servant (servant)->_mrp;
738      
739      kount = query_exec (mrp,  sortby, ls, 0, count, obj, 0, TRUE, CORBA_OBJECT_NIL, TRUE, traverse, ev); 
740
741      ls = g_list_next (ls); 
742     
743      if (sortby == Accessibility_Collection_SORT_ORDER_REVERSE_CANONICAL)
744        ls = g_list_reverse (ls);
745
746      return  _accessible_list_to_set (ls, kount);
747 }
748
749 static void
750 spi_collection_class_init (SpiCollectionClass *klass)
751 {
752
753     POA_Accessibility_Collection__epv *epv  = &klass->epv;
754
755     /*    
756       epv->isAncestorOf = impl_isAncestorOf; 
757     */
758
759     epv->createMatchRule = impl_createMatchRule;
760     epv->freeMatchRule   = impl_freeMatchRule;
761     epv->getMatches      = impl_getMatches;
762     epv->getMatchesTo    = impl_getMatchesTo;
763     epv->getMatchesFrom  = impl_getMatchesFrom;
764     
765
766     /*
767       epv->getActiveDescendant = impl_getActiveDescendant;
768     */
769
770 }
771
772 static void
773 spi_collection_init (SpiCollection *collection)
774 {
775
776   //collection->_mrp = g_new (MatchRulePrivate, 1);
777
778 }
779
780 BONOBO_TYPE_FUNC_FULL (SpiCollection,
781                        Accessibility_Collection,
782                        SPI_TYPE_BASE,
783                        spi_collection)
784