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