Add property accessible-visible-data
[platform/upstream/atk.git] / atk / atkobject.c
1 /* ATK -  Accessibility Toolkit
2  * Copyright 2001 Sun Microsystems Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include <string.h>
21
22 #include <glib-object.h>
23
24 #include "atk.h"
25
26 /* New GObject properties registered by AtkObject */
27 enum
28 {
29   PROP_0,  /* gobject convention */
30
31   PROP_NAME,
32   PROP_DESCRIPTION,
33   PROP_PARENT,      /* ancestry has changed */
34   PROP_CHILD,       /* a child has been added or removed */
35   PROP_STATE,       /* AtkStateSet for the object has changed */
36   PROP_TEXT,        /* Used only by AtkText implementors */
37   PROP_CARET,       /* Used only by AtkText implementors */
38   PROP_SELECTION,
39   PROP_VALUE,
40   PROP_VIBIBLE_DATA,
41   PROP_LAST         /* gobject convention */
42 };
43
44 enum {
45   CHILDREN_CHANGED,
46   FOCUS_EVENT,
47   LAST_SIGNAL
48 };
49
50 static void            atk_object_class_init       (AtkObjectClass  *klass);
51 static void            atk_object_init             (AtkObject       *accessible,
52                                                     AtkObjectClass  *klass);
53 static AtkRelationSet* atk_object_real_ref_relation_set (AtkObject *accessible);
54
55 static void            atk_object_real_set_property(GObject         *object,
56                                                     guint            prop_id,
57                                                     const GValue    *value,
58                                                     GParamSpec      *pspec);
59 static void            atk_object_real_get_property(GObject         *object,
60                                                     guint            prop_id,
61                                                     GValue          *value,
62                                                     GParamSpec      *pspec);
63 static void            atk_object_finalize         (GObject         *object);
64 static void            atk_object_real_set_role    (AtkObject       *object,
65                                                     AtkRole         role);
66
67 static guint atk_object_signals[LAST_SIGNAL] = { 0, };
68
69 static gpointer parent_class = NULL;
70
71 static const gchar* atk_object_name_property_name = "accessible-name";
72 static const gchar* atk_object_name_property_state = "accessible-state";
73 static const gchar* atk_object_name_property_description = "accessible-description";
74 static const gchar* atk_object_name_property_child = "accessible-child";
75 static const gchar* atk_object_name_property_parent = "accessible-parent";
76 static const gchar* atk_object_name_property_text = "accessible-text";
77 static const gchar* atk_object_name_property_caret = "accessible-caret";
78 static const gchar* atk_object_name_property_selection = "accessible-selection";
79 static const gchar* atk_object_name_property_value = "accessible-value";
80 static const gchar* atk_object_name_property_visible = "accessible-visible-data";
81
82 GType
83 atk_object_get_type (void)
84 {
85   static GType type = 0;
86
87   if (!type)
88     {
89       static const GTypeInfo typeInfo =
90       {
91         sizeof (AtkObjectClass),
92         (GBaseInitFunc) NULL,
93         (GBaseFinalizeFunc) NULL,
94         (GClassInitFunc) atk_object_class_init,
95         (GClassFinalizeFunc) NULL,
96         NULL,
97         sizeof (AtkObject),
98         0,
99         (GInstanceInitFunc) atk_object_init,
100       } ;
101       type = g_type_register_static (G_TYPE_OBJECT, "AtkObject", &typeInfo, 0) ;
102     }
103   return type;
104 }
105
106 static void
107 atk_object_class_init (AtkObjectClass *klass)
108 {
109   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
110
111   parent_class = g_type_class_ref (G_TYPE_OBJECT);
112
113   gobject_class->set_property = atk_object_real_set_property;
114   gobject_class->get_property = atk_object_real_get_property;
115   gobject_class->finalize = atk_object_finalize;
116
117   klass->ref_relation_set = atk_object_real_ref_relation_set;
118   klass->set_role = atk_object_real_set_role;
119
120   /*
121    * We do not define default signal handlers here
122    */
123   klass->focus_event = NULL;
124   klass->children_changed = NULL;
125
126   g_object_class_install_property (gobject_class,
127                                    PROP_NAME,
128                                    g_param_spec_string (atk_object_name_property_name,
129                                                         "Accessible Name",
130                                                         "Object instance\'s name formatted for "
131                                                            "assistive technology access",
132                                                         NULL,
133                                                         G_PARAM_READWRITE));
134   g_object_class_install_property (gobject_class,
135                                    PROP_DESCRIPTION,
136                                    g_param_spec_string (atk_object_name_property_description,
137                                                         "Accessible Description",
138                                                         "Description of an object, formatted for "
139                                                         "assistive technology access",
140                                                         NULL,
141                                                         G_PARAM_READWRITE));
142   g_object_class_install_property (gobject_class,
143                                    PROP_STATE,
144                                    g_param_spec_int    (atk_object_name_property_state,
145                                                         "Accessible State Set",
146                                                         "The accessible state set of this object "
147                                                         "or its UI component",
148                                                         0,
149                                                         G_MAXINT,
150                                                         0,
151                                                         G_PARAM_READWRITE));
152   g_object_class_install_property (gobject_class,
153                                    PROP_CHILD,
154                                    g_param_spec_object (atk_object_name_property_child,
155                                                         "Accessible Child",
156                                                         "Is used to notify that a child has been added or removed ",
157                                                         ATK_TYPE_OBJECT,
158                                                         G_PARAM_READWRITE));
159    g_object_class_install_property (gobject_class,
160                                     PROP_PARENT,
161                                    g_param_spec_object (atk_object_name_property_parent,
162                                                         "Accessible Parent",
163                                                         "Is used to notify that the parent has changed ",
164                                                         ATK_TYPE_OBJECT,
165                                                         G_PARAM_READWRITE));
166   g_object_class_install_property (gobject_class,
167                                    PROP_TEXT,
168                                    g_param_spec_object (atk_object_name_property_text,
169                                                         "Accessible Text",
170                                                         "Is used to notify that the text has changed ",
171                                                         ATK_TYPE_OBJECT,
172                                                         G_PARAM_READWRITE));
173   g_object_class_install_property (gobject_class,
174                                    PROP_CARET,
175                                    g_param_spec_int    (atk_object_name_property_caret,
176                                                         "Accessible Caret",
177                                                         "Is used to notify that the caret position has changed ",
178                                                         0,
179                                                         G_MAXINT,
180                                                         0,
181                                                         G_PARAM_READWRITE));
182   g_object_class_install_property (gobject_class,
183                                    PROP_SELECTION,
184                                    g_param_spec_object (atk_object_name_property_selection,
185                                                         "Accessible Selection",
186                                                         "Is used to notify that the selection has changed ",
187                                                         ATK_TYPE_OBJECT,
188                                                         G_PARAM_READWRITE));
189   g_object_class_install_property (gobject_class,
190                                    PROP_VALUE,
191                                    g_param_spec_double (atk_object_name_property_value,
192                                                         "Accessible Value",
193                                                         "Is used to notify that the value has changed ",
194                                                         0.0,
195                                                         G_MAXDOUBLE,
196                                                         0.0,
197                                                         G_PARAM_READWRITE));
198   g_object_class_install_property (gobject_class,
199                                    PROP_SELECTION,
200                                    g_param_spec_object (atk_object_name_property_visible,
201                                                         "Accessible Visible Data",
202                                                         "Is used to notify that the visual appearance of the object has changed ",
203                                                         ATK_TYPE_OBJECT,
204                                                         G_PARAM_READWRITE));
205   /*
206    * The signal "children_changed" supports two details:
207    * "add" and "remove"
208    */
209   atk_object_signals[CHILDREN_CHANGED] =
210     g_signal_newc ("children_changed",
211                    G_TYPE_FROM_CLASS (klass),
212                    G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
213                    G_STRUCT_OFFSET (AtkObjectClass, children_changed),
214                    NULL, NULL,
215                    g_cclosure_marshal_VOID__UINT_POINTER,
216                    G_TYPE_NONE,
217                    2, G_TYPE_UINT, ATK_TYPE_OBJECT);
218   atk_object_signals[FOCUS_EVENT] =
219     g_signal_newc ("focus_event",
220                    G_TYPE_FROM_CLASS (klass),
221                    G_SIGNAL_RUN_LAST,
222                    G_STRUCT_OFFSET (AtkObjectClass, focus_event), 
223                    NULL, NULL,
224                    g_cclosure_marshal_VOID__BOOLEAN,
225                    G_TYPE_NONE,
226                    1, G_TYPE_BOOLEAN);
227 }
228
229 static void
230 atk_object_init  (AtkObject        *accessible,
231                   AtkObjectClass   *klass)
232 {
233 }
234
235 GType
236 atk_implementor_get_type (void)
237 {
238   static GType type = 0;
239
240   if (!type)
241     {
242       static const GTypeInfo typeInfo =
243       {
244         sizeof (AtkImplementorIface),
245         (GBaseInitFunc) NULL,
246         (GBaseFinalizeFunc) NULL,
247       } ;
248
249       type = g_type_register_static (G_TYPE_INTERFACE, "AtkImplementorIface", &typeInfo, 0) ;
250     }
251
252   return type;
253 }
254
255 /**
256  * atk_object_get_name:
257  * @accessible: an #AtkObject
258  *
259  * Gets the accessible name of the accessible
260  *
261  * Returns: a character string representing the accessible name of the object.
262  **/
263 G_CONST_RETURN gchar*
264 atk_object_get_name (AtkObject *accessible)
265 {
266   AtkObjectClass *klass;
267
268   g_return_val_if_fail (accessible != NULL, NULL);
269   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
270
271   klass = ATK_OBJECT_GET_CLASS (accessible);
272   if (klass->get_name)
273     return (klass->get_name) (accessible);
274   else
275     return NULL;
276 }
277
278 /**
279  * atk_object_get_description:
280  * @accessible: an #AtkObject
281  *
282  * Gets the accessible description of the accessible
283  *
284  * Returns: a character string representing the accessible description
285  * of the accessible.
286  *
287  **/
288 G_CONST_RETURN gchar*
289 atk_object_get_description (AtkObject *accessible)
290 {
291   AtkObjectClass *klass;
292
293   g_return_val_if_fail (accessible != NULL, NULL);
294   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
295
296   klass = ATK_OBJECT_GET_CLASS (accessible);
297   if (klass->get_description)
298     return (klass->get_description) (accessible);
299   else
300     return NULL;
301 }
302
303 /**
304  * atk_object_get_parent:
305  * @accessible: an #AtkObject
306  *
307  * Gets the accessible parent of the accessible
308  *
309  * Returns: a #AtkObject representing the accessible parent of the accessible
310  **/
311 AtkObject*
312 atk_object_get_parent (AtkObject *accessible)
313 {
314   AtkObjectClass *klass;
315
316   g_return_val_if_fail (accessible != NULL, NULL);
317   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
318
319   klass = ATK_OBJECT_GET_CLASS (accessible);
320   if (klass->get_parent)
321     return (klass->get_parent) (accessible);
322   else
323     return NULL;
324 }
325
326 /**
327  * atk_object_get_n_accessible_children:
328  * @accessible: an #AtkObject
329  *
330  * Gets the number of accessible children of the accessible
331  *
332  * Returns: an integer representing the number of accessible children
333  * of the accessible.
334  **/
335 gint
336 atk_object_get_n_accessible_children (AtkObject *accessible)
337 {
338   AtkObjectClass *klass;
339
340   g_return_val_if_fail (accessible != NULL, 0);
341   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
342
343   klass = ATK_OBJECT_GET_CLASS (accessible);
344   if (klass->get_n_children)
345     return (klass->get_n_children) (accessible);
346   else
347     return 0;
348 }
349
350 /**
351  * atk_object_ref_accessible_child:
352  * @accessible: an #AtkObject
353  * @i: a gint representing the position of the child, starting from 0
354  *
355  * Gets a reference to the specified accessible child of the object.
356  * The accessible children are 0-based so the first accessible child is
357  * at index 0, the second at index 1 and so on.
358  *
359  * Returns: an #AtkObject representing the specified accessible child
360  * of the accessible.
361  **/
362 AtkObject*
363 atk_object_ref_accessible_child (AtkObject   *accessible,
364                                  gint        i)
365 {
366   AtkObjectClass *klass;
367
368   g_return_val_if_fail (accessible != NULL, NULL);
369   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
370
371   klass = ATK_OBJECT_GET_CLASS (accessible);
372   if (klass->ref_child)
373     return (klass->ref_child) (accessible, i);
374   else
375     return NULL;
376 }
377
378 /**
379  * atk_object_ref_relation_set:
380  * @accessible: an #AtkObject
381  *
382  * Gets the RelationSet associated with the object
383  *
384  * Returns: an #AtkRelationSet representing the relation set of the object.
385  **/
386 AtkRelationSet*
387 atk_object_ref_relation_set (AtkObject *accessible)
388 {
389   AtkObjectClass *klass;
390
391   g_return_val_if_fail (accessible != NULL, NULL);
392   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
393
394   klass = ATK_OBJECT_GET_CLASS (accessible);
395   if (klass->ref_relation_set)
396     return (klass->ref_relation_set) (accessible);
397   else
398     return NULL;
399 }
400
401 /**
402  * atk_role_register:
403  * @name: a character string describing the new role.
404  *
405  * Returns: an #AtkRole for the new role.
406  **/
407 AtkRole
408 atk_role_register (const gchar *name)
409 {
410   /* TODO: associate name with new type */
411   static guint type = ATK_ROLE_LAST_DEFINED;
412   return (++type);
413 }
414
415 /**
416  * atk_object_get_role:
417  * @accessible: an #AtkObject
418  *
419  * Gets the role of the accessible
420  *
421  * Returns: an #AtkRole which is the role of the accessible
422  **/
423 AtkRole
424 atk_object_get_role (AtkObject *accessible) {
425   AtkObjectClass *klass;
426
427   g_return_val_if_fail (accessible != NULL, ATK_ROLE_UNKNOWN);
428   g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_ROLE_UNKNOWN);
429
430   klass = ATK_OBJECT_GET_CLASS (accessible);
431   if (klass->get_role)
432     return (klass->get_role) (accessible);
433   else
434     return ATK_ROLE_UNKNOWN;
435 }
436
437 /**
438  * atk_object_ref_state_set:
439  * @accessible: an #AtkObject
440  *
441  * Gets a reference to the state set of the accessible; the caller should
442  * unreference it.
443  *
444  * Returns: a reference to an #AtkStateSet which is the state
445  * set of the accessible
446  **/
447 AtkStateSet*
448 atk_object_ref_state_set (AtkObject *accessible) {
449   AtkObjectClass *klass;
450
451   g_return_val_if_fail (accessible != NULL, NULL);
452   g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
453
454   klass = ATK_OBJECT_GET_CLASS (accessible);
455   if (klass->ref_state_set)
456     return (klass->ref_state_set) (accessible);
457   else
458     return NULL;
459 }
460
461 /**
462  * atk_object_get_index_in_parent:
463  * @accessible: an #AtkObject
464  *
465  * Gets the 0-based index of this accessible in its parent; returns -1 if the
466  * accessible does not have an accessible parent.
467  *
468  * Returns: an integer which is the index of the accessible in its parent
469  **/
470 gint
471 atk_object_get_index_in_parent (AtkObject *accessible)
472 {
473   AtkObjectClass *klass;
474
475   g_return_val_if_fail (accessible != NULL, -1);
476   g_return_val_if_fail (ATK_OBJECT (accessible), -1);
477
478   klass = ATK_OBJECT_GET_CLASS (accessible);
479   if (klass->get_index_in_parent)
480     return (klass->get_index_in_parent) (accessible);
481   else
482     return -1;
483 }
484
485 /**
486  * atk_object_set_name:
487  * @accessible: an #AtkObject
488  * @name: a character string to be set as the accessible name
489  *
490  * Sets the accessible name of the accessible
491  **/
492 void
493 atk_object_set_name (AtkObject    *accessible,
494                      const gchar  *name)
495 {
496   AtkObjectClass *klass;
497
498   g_return_if_fail (accessible != NULL);
499   g_return_if_fail (ATK_IS_OBJECT (accessible));
500   g_return_if_fail (name != NULL);
501
502   klass = ATK_OBJECT_GET_CLASS (accessible);
503   if (klass->set_name)
504   {
505     (klass->set_name) (accessible, name);
506     g_object_notify (G_OBJECT (accessible), atk_object_name_property_name);
507   }
508 }
509
510 /**
511  * atk_object_set_description:
512  * @accessible: an #AtkObject
513  * @description : a character string to be set as the accessible description
514  *
515  * Sets the accessible description of the accessible
516  **/
517 void
518 atk_object_set_description (AtkObject   *accessible,
519                             const gchar *description)
520 {
521   AtkObjectClass *klass;
522
523   g_return_if_fail (accessible != NULL);
524   g_return_if_fail (ATK_IS_OBJECT (accessible));
525   g_return_if_fail (description != NULL);
526
527   klass = ATK_OBJECT_GET_CLASS (accessible);
528   if (klass->set_description)
529   {
530     (klass->set_description) (accessible, description);
531     g_object_notify (G_OBJECT (accessible), atk_object_name_property_description);
532   }
533 }
534
535 /**
536  * atk_object_set_parent:
537  * @accessible: an #AtkObject
538  * @parent : an #AtkObject to be set as the accessible parent
539  *
540  * Sets the accessible parent of the accessible
541  **/
542 void
543 atk_object_set_parent (AtkObject *accessible,
544                        AtkObject *parent)
545 {
546   AtkObjectClass *klass;
547
548   g_return_if_fail (accessible != NULL);
549   g_return_if_fail (ATK_IS_OBJECT (accessible));
550
551   klass = ATK_OBJECT_GET_CLASS (accessible);
552   if (klass->set_parent)
553     (klass->set_parent) (accessible, parent);
554 }
555
556 /**
557  * atk_object_set_role:
558  * @accessible: an #AtkObject
559  * @role : an #AtkRole to be set as the role
560  *
561  * Sets the role of the accessible
562  **/
563 void
564 atk_object_set_role (AtkObject *accessible, 
565                      AtkRole   role)
566 {
567   AtkObjectClass *klass;
568
569   g_return_if_fail (accessible != NULL);
570   g_return_if_fail (ATK_IS_OBJECT (accessible));
571
572   klass = ATK_OBJECT_GET_CLASS (accessible);
573   if (klass->set_role)
574     (klass->set_role) (accessible, role);
575 }
576
577 /**
578  * atk_object_connect_property_change_handler:
579  * @accessible: an #AtkObject
580  * @handler : a function to be called when a property changes its value
581  *
582  * Specifies a function to be called when a property changes value.
583  *
584  * Returns: a #guint which is the handler id used in 
585  * atk_object_remove_property_change_handler()
586  **/
587 guint
588 atk_object_connect_property_change_handler (AtkObject *accessible,
589                                             AtkPropertyChangeHandler *handler)
590 {
591   AtkObjectClass *klass;
592
593   g_return_val_if_fail (accessible != NULL, 0);
594   g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
595   g_return_val_if_fail ((handler != NULL), 0);
596
597   klass = ATK_OBJECT_GET_CLASS (accessible);
598   if (klass->connect_property_change_handler)
599     return (klass->connect_property_change_handler) (accessible, handler);
600   else
601     return 0;
602 }
603
604 /**
605  * atk_object_remove_property_change_handler:
606  * @accessible: an #AtkObject
607  * @handler_id : a guint which identifies the handler to be removed.
608  * 
609  * Removes a property change handler.
610  **/
611 void
612 atk_object_remove_property_change_handler  (AtkObject *accessible,
613                                             guint      handler_id)
614 {
615   AtkObjectClass *klass;
616
617   g_return_if_fail (accessible != NULL);
618   g_return_if_fail (ATK_IS_OBJECT (accessible));
619
620   klass = ATK_OBJECT_GET_CLASS (accessible);
621   if (klass->remove_property_change_handler)
622     (klass->remove_property_change_handler) (accessible, handler_id);
623 }
624
625 /**
626  * atk_implementor_ref_accessible:
627  * @implementor: The #GObject instance which should implement #AtkImplementorIface
628  * if a non-null return value is required.
629  * 
630  * Gets a reference to an object's #AtkObject implementation, if
631  * the object implements #AtkObjectIface
632  *
633  * Returns: a reference to an object's #AtkObject implementation
634  */
635 AtkObject *
636 atk_implementor_ref_accessible (AtkImplementor *object)
637 {
638   AtkImplementorIface *iface;
639   AtkObject           *accessible = NULL;
640
641   g_return_val_if_fail (object != NULL, NULL);
642   g_return_val_if_fail (ATK_IS_IMPLEMENTOR (object), NULL);
643
644   iface = ATK_IMPLEMENTOR_GET_IFACE (object);
645
646   if (iface != NULL) 
647     accessible =  iface->ref_accessible (object);
648
649   g_return_val_if_fail ((accessible != NULL), NULL);
650
651   return accessible;
652 }
653
654 static AtkRelationSet*
655 atk_object_real_ref_relation_set (AtkObject *accessible)
656 {
657   if (accessible->relation_set)
658     g_object_ref (accessible->relation_set); 
659
660   return accessible->relation_set;
661 }
662
663 static void
664 atk_object_real_set_property (GObject      *object,
665                               guint         prop_id,
666                               const GValue *value,
667                               GParamSpec   *pspec)
668 {
669   AtkObject *accessible;
670
671   accessible = ATK_OBJECT (object);
672
673   switch (prop_id)
674   {
675     case PROP_NAME:
676       atk_object_set_name (accessible, g_value_get_string (value));
677       break;
678     case PROP_DESCRIPTION:
679       atk_object_set_description (accessible, g_value_get_string (value));
680       break;
681     case PROP_STATE:
682       g_print ("This interface does not support setting the state set of an accessible object\n");
683       break;
684     case PROP_VALUE:
685       if (ATK_IS_VALUE (accessible))
686         atk_value_set_current_value (ATK_VALUE (accessible), value);
687       break;
688     default:
689       break;
690   }
691 }
692
693 static void
694 atk_object_real_get_property (GObject      *object,
695                               guint         prop_id,
696                               GValue       *value,
697                               GParamSpec   *pspec)
698 {
699   AtkObject *accessible;
700
701   accessible = ATK_OBJECT (object);
702
703   switch (prop_id)
704   {
705     case PROP_NAME:
706       g_value_set_string (value, atk_object_get_name (accessible));
707       break;
708     case PROP_DESCRIPTION:
709       g_value_set_string (value, atk_object_get_description (accessible));
710       break;
711     case PROP_VALUE:
712       if (ATK_IS_VALUE (accessible))
713         atk_value_get_current_value (ATK_VALUE (accessible), value);
714       break;
715     default:
716       break;
717   }
718 }
719
720 static void
721 atk_object_finalize (GObject *object)
722 {
723   AtkObject        *accessible;
724
725   g_return_if_fail (ATK_IS_OBJECT (object));
726
727   accessible = ATK_OBJECT (object);
728
729   g_free (accessible->name);
730   g_free (accessible->description);
731
732   /*
733    * Free memory allocated for relation set if it have been allocated.
734    */
735   if (accessible->relation_set)
736   {
737     g_object_unref (accessible->relation_set);
738   }
739
740   G_OBJECT_CLASS (parent_class)->finalize (object);
741 }
742
743 static void
744 atk_object_real_set_role (AtkObject *object,
745                           AtkRole   role)
746 {
747   object->role = role;
748 }