/* * We redefine atk_class->ref_relation_set instead of just calling * atk_object_add_relationship on ev_page_accessible_new because at * that moment not all the pages could be created, being easier add * the relation on demand. */ static AtkRelationSet * ev_page_accessible_ref_relation_set (AtkObject *accessible) { gint n_pages; EvPageAccessible *self; AtkRelationSet *relation_set; AtkObject *accessible_array[1]; AtkRelation *relation; g_return_val_if_fail (EV_IS_PAGE_ACCESSIBLE (accessible), NULL); self = EV_PAGE_ACCESSIBLE (accessible); relation_set = ATK_OBJECT_CLASS (ev_page_accessible_parent_class)->ref_relation_set (accessible); if (relation_set == NULL) return NULL; n_pages = ev_view_accessible_get_n_pages (self->priv->view_accessible); if (n_pages == 0) return relation_set; if ((self->priv->page + 1) < n_pages && !atk_relation_set_contains (relation_set, ATK_RELATION_FLOWS_TO)) { AtkObject *next_page; next_page = atk_object_ref_accessible_child (ATK_OBJECT (self->priv->view_accessible), self->priv->page + 1); accessible_array [0] = next_page; relation = atk_relation_new (accessible_array, 1, ATK_RELATION_FLOWS_TO); atk_relation_set_add (relation_set, relation); g_object_unref (relation); g_object_unref (next_page); } if (self->priv->page > 0 && !atk_relation_set_contains (relation_set, ATK_RELATION_FLOWS_FROM)) { AtkObject *prev_page; prev_page = atk_object_ref_accessible_child (ATK_OBJECT (self->priv->view_accessible), self->priv->page - 1); accessible_array [0] = prev_page; relation = atk_relation_new (accessible_array, 1, ATK_RELATION_FLOWS_FROM); atk_relation_set_add (relation_set, relation); g_object_unref (relation); g_object_unref (prev_page); } return relation_set; }
/** * atk_relation_set_add: * @set: an #AtkRelationSet * @relation: an #AtkRelation * * Add a new relation to the current relation set if it is not already * present. * This function ref's the AtkRelation so the caller of this function * should unref it to ensure that it will be destroyed when the AtkRelationSet * is destroyed. **/ void atk_relation_set_add (AtkRelationSet *set, AtkRelation *relation) { AtkRelationType relationship; g_return_if_fail (ATK_IS_RELATION_SET (set)); g_return_if_fail (relation != NULL); if (set->relations == NULL) { set->relations = g_ptr_array_new (); } relationship = atk_relation_get_relation_type (relation); if (!atk_relation_set_contains (set, relationship)) { g_ptr_array_add (set->relations, relation); g_object_ref (relation); } else { AtkRelation *exist_relation; gint i; exist_relation = atk_relation_set_get_relation_by_type (set, relationship); for (i = 0; i < relation->target->len; i++) { AtkObject *target = g_ptr_array_index(relation->target, i); atk_relation_add_target (exist_relation, target); } } }
/** * atk_relation_set_remove: * @set: an #AtkRelationSet * @relation: an #AtkRelation * * Removes a relation from the relation set. * This function unref's the #AtkRelation so it will be deleted unless there * is another reference to it. **/ void atk_relation_set_remove (AtkRelationSet *set, AtkRelation *relation) { GPtrArray *array_item; AtkRelationType relationship; g_return_if_fail (ATK_IS_RELATION_SET (set)); array_item = set->relations; if (array_item == NULL) return; if (g_ptr_array_remove (array_item, relation)) { g_object_unref (relation); } else { relationship = atk_relation_get_relation_type (relation); if (atk_relation_set_contains (set, relationship)) { AtkRelation *exist_relation; gint i; exist_relation = atk_relation_set_get_relation_by_type (set, relationship); for (i = 0; i < relation->target->len; i++) { AtkObject *target = g_ptr_array_index(relation->target, i); atk_relation_remove_target (exist_relation, target); } } } }
static AtkRelationSet * gtk_widget_accessible_ref_relation_set (AtkObject *obj) { GtkWidget *widget; AtkRelationSet *relation_set; GtkWidget *label; AtkObject *array[1]; AtkRelation* relation; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); if (widget == NULL) return NULL; relation_set = ATK_OBJECT_CLASS (_gtk_widget_accessible_parent_class)->ref_relation_set (obj); if (GTK_IS_BOX (widget)) return relation_set; if (!atk_relation_set_contains (relation_set, ATK_RELATION_LABELLED_BY)) { label = find_label (widget); if (label == NULL) { if (GTK_IS_BUTTON (widget)) /* * Handle the case where GnomeIconEntry is the mnemonic widget. * The GtkButton which is a grandchild of the GnomeIconEntry * should really be the mnemonic widget. See bug #133967. */ { GtkWidget *temp_widget; temp_widget = gtk_widget_get_parent (widget); if (GTK_IS_ALIGNMENT (temp_widget)) { temp_widget = gtk_widget_get_parent (temp_widget); if (GTK_IS_BOX (temp_widget)) { label = find_label (temp_widget); if (!label) label = find_label (gtk_widget_get_parent (temp_widget)); } } } else if (GTK_IS_COMBO_BOX (widget)) /* * Handle the case when GtkFileChooserButton is the mnemonic * widget. The GtkComboBox which is a child of the * GtkFileChooserButton should be the mnemonic widget. * See bug #359843. */ { GtkWidget *temp_widget; temp_widget = gtk_widget_get_parent (widget); if (GTK_IS_BOX (temp_widget)) { label = find_label (temp_widget); } } } if (label) { 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; }
AtkRelationSet* gail_label_ref_relation_set (AtkObject *obj) { GtkWidget *widget; AtkRelationSet *relation_set; g_return_val_if_fail (GAIL_IS_LABEL (obj), NULL); widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); if (widget == NULL) /* * State is defunct */ return NULL; relation_set = ATK_OBJECT_CLASS (gail_label_parent_class)->ref_relation_set (obj); if (!atk_relation_set_contains (relation_set, ATK_RELATION_LABEL_FOR)) { /* * Get the mnemonic widget * * The relation set is not updated if the mnemonic widget is changed */ GtkWidget *mnemonic_widget = gtk_label_get_mnemonic_widget (GTK_LABEL (widget)); if (mnemonic_widget) { AtkObject *accessible_array[1]; AtkRelation* relation; if (!gtk_widget_get_can_focus (mnemonic_widget)) { /* * Handle the case where a GtkFileChooserButton is specified as the * mnemonic widget. use the combobox which is a child of the * GtkFileChooserButton as the mnemonic widget. See bug #359843. */ if (GTK_IS_BOX (mnemonic_widget)) { GList *list, *tmpl; list = gtk_container_get_children (GTK_CONTAINER (mnemonic_widget)); if (g_list_length (list) == 2) { tmpl = g_list_last (list); if (GTK_IS_COMBO_BOX(tmpl->data)) { mnemonic_widget = GTK_WIDGET(tmpl->data); } } g_list_free (list); } /* * Handle the case where a GnomeIconEntry is specified as the * mnemonic widget. use the button which is a grandchild of the * GnomeIconEntry as the mnemonic widget. See bug #133967. */ else if (GTK_IS_BOX (mnemonic_widget)) { GList *list; list = gtk_container_get_children (GTK_CONTAINER (mnemonic_widget)); if (g_list_length (list) == 1) { if (GTK_IS_ALIGNMENT (list->data)) { GtkWidget *temp_widget; temp_widget = gtk_bin_get_child (GTK_BIN (list->data)); if (GTK_IS_BUTTON (temp_widget)) mnemonic_widget = temp_widget; } else if (GTK_IS_HBOX (list->data)) { GtkWidget *temp_widget; temp_widget = GTK_WIDGET (list->data); g_list_free (list); list = gtk_container_get_children (GTK_CONTAINER (temp_widget)); } } g_list_free (list); } } accessible_array[0] = gtk_widget_get_accessible (mnemonic_widget); relation = atk_relation_new (accessible_array, 1, ATK_RELATION_LABEL_FOR); atk_relation_set_add (relation_set, relation); /* * Unref the relation so that it is not leaked. */ g_object_unref (relation); } } return relation_set; }
static AtkRelationSet * gtk_label_accessible_ref_relation_set (AtkObject *obj) { GtkWidget *widget; AtkRelationSet *relation_set; g_return_val_if_fail (GTK_IS_LABEL_ACCESSIBLE (obj), NULL); widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); if (widget == NULL) return NULL; relation_set = ATK_OBJECT_CLASS (_gtk_label_accessible_parent_class)->ref_relation_set (obj); if (!atk_relation_set_contains (relation_set, ATK_RELATION_LABEL_FOR)) { /* Get the mnemonic widget. * The relation set is not updated if the mnemonic widget is changed */ GtkWidget *mnemonic_widget; mnemonic_widget = gtk_label_get_mnemonic_widget (GTK_LABEL (widget)); if (mnemonic_widget) { AtkObject *accessible_array[1]; AtkRelation* relation; if (!gtk_widget_get_can_focus (mnemonic_widget)) { /* * Handle the case where a GtkFileChooserButton is specified * as the mnemonic widget. use the combobox which is a child of the * GtkFileChooserButton as the mnemonic widget. See bug #359843. */ if (GTK_IS_BOX (mnemonic_widget)) { GList *list, *tmpl; list = gtk_container_get_children (GTK_CONTAINER (mnemonic_widget)); if (g_list_length (list) == 2) { tmpl = g_list_last (list); if (GTK_IS_COMBO_BOX(tmpl->data)) { mnemonic_widget = GTK_WIDGET(tmpl->data); } } g_list_free (list); } } accessible_array[0] = gtk_widget_get_accessible (mnemonic_widget); relation = atk_relation_new (accessible_array, 1, ATK_RELATION_LABEL_FOR); atk_relation_set_add (relation_set, relation); /* * Unref the relation so that it is not leaked. */ g_object_unref (relation); } } return relation_set; }