From 12e1d4fc27f2d5e99f45ed2648e0ff42fe3c6ab3 Mon Sep 17 00:00:00 2001 From: Li Yuan Date: Tue, 11 Nov 2008 07:17:06 +0000 Subject: [PATCH] Bug #477708. Only remove the target, not the relation if there are still 2008-11-10 Li Yuan * atk/atkobject.c: (atk_object_remove_relationship): Bug #477708. Only remove the target, not the relation if there are still are targets. * atk/atkrelation.c: (atk_relation_remove_target): * atk/atkrelation.h: New API. * atk/atkrelationset.c: (atk_relation_set_add), (atk_relation_set_remove): Add/remove the new relation's targets to/from the existed relation if there has been a relation with the same type. * atk/atkstateset.c: (atk_state_set_or_sets): Bug #478595. Return NULL if sets are empty. svn path=/trunk/; revision=1297 --- ChangeLog | 14 ++++++++++++++ atk/atkobject.c | 26 ++++++++------------------ atk/atkrelation.c | 29 +++++++++++++++++++++++++++++ atk/atkrelation.h | 2 ++ atk/atkrelationset.c | 30 +++++++++++++++++++++++++++++- atk/atkstateset.c | 7 +++++-- 6 files changed, 87 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 871d4c3..9f8d904 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2008-11-10 Li Yuan + * atk/atkobject.c: (atk_object_remove_relationship): + Bug #477708. Only remove the target, not the relation if + there are still are targets. + * atk/atkrelation.c: (atk_relation_remove_target): + * atk/atkrelation.h: New API. + * atk/atkrelationset.c: (atk_relation_set_add), + (atk_relation_set_remove): + Add/remove the new relation's targets to/from the existed + relation if there has been a relation with the same type. + * atk/atkstateset.c: (atk_state_set_or_sets): + Bug #478595. Return NULL if sets are empty. + +2008-11-10 Li Yuan + * atk/atkrelationset.c: (atk_relation_set_add): Don't ref the relation if it is not added. diff --git a/atk/atkobject.c b/atk/atkobject.c index 80af514..234a68a 100755 --- a/atk/atkobject.c +++ b/atk/atkobject.c @@ -1522,32 +1522,22 @@ atk_object_remove_relationship (AtkObject *object, AtkRelationType relationship, AtkObject *target) { - gint n_relations, i; gboolean ret = FALSE; AtkRelation *relation; + GPtrArray *array; g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE); g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE); - n_relations = atk_relation_set_get_n_relations (object->relation_set); - for (i = 0; i < n_relations; i++) - { - relation = atk_relation_set_get_relation (object->relation_set, i); - if (atk_relation_get_relation_type (relation) == relationship) - { - GPtrArray *array; + relation = atk_relation_set_get_relation_by_type (object->relation_set, relationship); - array = atk_relation_get_target (relation); - - if (g_ptr_array_index (array, 0) == target) - { - atk_relation_set_remove (object->relation_set, relation); - ret = TRUE; - break; - } - } + if (relation) + { + ret = atk_relation_remove_target (relation, target); + array = atk_relation_get_target (relation); + if (!array || array->len == 0) + atk_relation_set_remove (object->relation_set, relation); } - return ret; } diff --git a/atk/atkrelation.c b/atk/atkrelation.c index 92000c9..970d947 100755 --- a/atk/atkrelation.c +++ b/atk/atkrelation.c @@ -333,6 +333,35 @@ atk_relation_add_target (AtkRelation *relation, g_object_weak_ref (G_OBJECT (target), (GWeakNotify) delete_object_while_in_relation, relation->target); } +/** + * atk_relation_remove_target: + * @relation: an #AtkRelation + * @target: an #AtkObject + * + * Remove the specified AtkObject from the target for the relation. + * + * Returns TRUE if the removal is successful. + **/ + +gboolean +atk_relation_remove_target (AtkRelation *relation, + AtkObject *target) +{ + gboolean ret = FALSE; + GPtrArray *array; + + array = atk_relation_get_target (relation); + + if (array && g_ptr_array_remove (array, target)) + { + g_object_weak_unref (G_OBJECT (target), + (GWeakNotify) delete_object_while_in_relation, + relation->target); + ret = TRUE; + } + return ret; +} + static void atk_relation_finalize (GObject *object) { diff --git a/atk/atkrelation.h b/atk/atkrelation.h index 88db375..794747c 100755 --- a/atk/atkrelation.h +++ b/atk/atkrelation.h @@ -81,6 +81,8 @@ AtkRelationType atk_relation_get_relation_type (AtkRelation *relation GPtrArray* atk_relation_get_target (AtkRelation *relation); void atk_relation_add_target (AtkRelation *relation, AtkObject *target); +gboolean atk_relation_remove_target (AtkRelation *relation, + AtkObject *target); G_END_DECLS diff --git a/atk/atkrelationset.c b/atk/atkrelationset.c index 2264595..f594cac 100755 --- a/atk/atkrelationset.c +++ b/atk/atkrelationset.c @@ -123,17 +123,33 @@ 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); + } + } + } } /** @@ -160,12 +176,24 @@ atk_relation_set_add (AtkRelationSet *set, { 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); + } + } } /** diff --git a/atk/atkstateset.c b/atk/atkstateset.c index 2b98fa4..b7654b0 100755 --- a/atk/atkstateset.c +++ b/atk/atkstateset.c @@ -308,8 +308,11 @@ atk_state_set_or_sets (AtkStateSet *set, state = real_set->state | real_compare_set->state; - return_set = atk_state_set_new(); - ((AtkRealStateSet *) return_set)->state = state; + if (state) + { + return_set = atk_state_set_new(); + ((AtkRealStateSet *) return_set)->state = state; + } return return_set; } -- 2.7.4