diff --git a/src/lib/elementary/efl_access_object.c b/src/lib/elementary/efl_access_object.c index 49e9dc39b8..b9626274e2 100644 --- a/src/lib/elementary/efl_access_object.c +++ b/src/lib/elementary/efl_access_object.c @@ -123,7 +123,7 @@ struct _Efl_Access_Event_Handler struct _Efl_Access_Object_Data { - Efl_Access_Relation_Set relations; + Eina_List *relations; Eina_List *attr_list; const char *name; const char *description; @@ -377,10 +377,10 @@ _efl_access_object_state_set_get(const Eo *obj EINA_UNUSED, Efl_Access_Object_Da return 0; } -EOLIAN Efl_Access_Relation_Set -_efl_access_object_relation_set_get(const Eo *obj EINA_UNUSED, Efl_Access_Object_Data *pd) +EOLIAN Eina_Iterator * +_efl_access_object_relations_get(const Eo *obj EINA_UNUSED, Efl_Access_Object_Data *pd) { - return efl_access_relation_set_clone(pd->relations); + return eina_list_iterator_new(pd->relations); } EAPI void efl_access_attributes_list_free(Eina_List *list) @@ -472,64 +472,60 @@ _efl_access_object_translation_domain_get(const Eo *obj EINA_UNUSED, Efl_Access_ return pd->translation_domain; } -EAPI void -efl_access_relation_free(Efl_Access_Relation *relation) -{ - eina_list_free(relation->objects); - free(relation); -} - -EAPI Efl_Access_Relation * -efl_access_relation_clone(const Efl_Access_Relation *relation) -{ - Efl_Access_Relation *ret = calloc(1, sizeof(Efl_Access_Relation)); - if (!ret) return NULL; - - ret->type = relation->type; - ret->objects = eina_list_clone(relation->objects); - return ret; -} - static void _on_rel_obj_del(void *data, const Efl_Event *event) { - Efl_Access_Relation_Set *set = data; + Efl_Access_Object_Data *sd = data; Efl_Access_Relation *rel; Eina_List *l, *l2, *p, *p2; Eo *rel_obj; - EINA_LIST_FOREACH_SAFE(*set, l, l2, rel) + EINA_LIST_FOREACH_SAFE(sd->relations, l, l2, rel) { EINA_LIST_FOREACH_SAFE(rel->objects, p, p2, rel_obj) { - if (rel_obj == event->object) + if (rel_obj == event->object) rel->objects = eina_list_remove_list(rel->objects, p); } if (!rel->objects) { - *set = eina_list_remove_list(*set, l); + sd->relations = eina_list_remove_list(sd->relations, l); free(rel); } } } -EAPI Eina_Bool -efl_access_relation_set_relation_append(Efl_Access_Relation_Set *set, Efl_Access_Relation_Type type, const Eo *rel_obj) +static void +efl_access_relation_set_free(Efl_Access_Object_Data *sd) +{ + Efl_Access_Relation *rel; + Eo *obj; + + EINA_LIST_FREE(sd->relations, rel) + { + Eina_List *l; + + EINA_LIST_FOREACH(rel->objects, l, obj) + efl_event_callback_del(obj, EFL_EVENT_DEL, _on_rel_obj_del, sd); + eina_list_free(rel->objects); + free(rel); + } +} + +EOLIAN static Eina_Bool +_efl_access_object_relationship_append(Eo *obj EINA_UNUSED, Efl_Access_Object_Data *sd, Efl_Access_Relation_Type type, const Efl_Access_Object *relation) { Efl_Access_Relation *rel; Eina_List *l; - if (!efl_isa(rel_obj, EFL_ACCESS_OBJECT_MIXIN)) - return EINA_FALSE; - - EINA_LIST_FOREACH(*set, l, rel) + EINA_LIST_FOREACH(sd->relations, l, rel) { if (rel->type == type) { - if (!eina_list_data_find(rel->objects, rel_obj)) + if (!eina_list_data_find(rel->objects, relation)) { - rel->objects = eina_list_append(rel->objects, rel_obj); - efl_event_callback_add((Eo *) rel_obj, EFL_EVENT_DEL, _on_rel_obj_del, set); + rel->objects = eina_list_append(rel->objects, relation); + efl_event_callback_add((Eo *) relation, EFL_EVENT_DEL, _on_rel_obj_del, sd); } return EINA_TRUE; } @@ -539,108 +535,56 @@ efl_access_relation_set_relation_append(Efl_Access_Relation_Set *set, Efl_Access if (!rel) return EINA_FALSE; rel->type = type; - rel->objects = eina_list_append(rel->objects, rel_obj); - *set = eina_list_append(*set, rel); + rel->objects = eina_list_append(rel->objects, relation); + sd->relations = eina_list_append(sd->relations, rel); + + efl_event_callback_add((Eo *) relation, EFL_EVENT_DEL, _on_rel_obj_del, sd); - efl_event_callback_add((Eo *) rel_obj, EFL_EVENT_DEL, _on_rel_obj_del, set); return EINA_TRUE; } -EAPI void -efl_access_relation_set_relation_remove(Efl_Access_Relation_Set *set, Efl_Access_Relation_Type type, const Eo *rel_obj) -{ - Eina_List *l; - Efl_Access_Relation *rel; - - EINA_LIST_FOREACH(*set, l, rel) - { - if (rel->type == type) - { - if (eina_list_data_find(rel->objects, rel_obj)) - { - efl_event_callback_del((Eo *) rel_obj, EFL_EVENT_DEL, _on_rel_obj_del, set); - rel->objects = eina_list_remove(rel->objects, rel_obj); - } - if (!rel->objects) - { - *set = eina_list_remove(*set, rel); - efl_access_relation_free(rel); - } - return; - } - } -} - -EAPI void -efl_access_relation_set_relation_type_remove(Efl_Access_Relation_Set *set, Efl_Access_Relation_Type type) -{ - Eina_List *l; - Efl_Access_Relation *rel; - Eo *obj; - - EINA_LIST_FOREACH(*set, l, rel) - { - if (rel->type == type) - { - EINA_LIST_FOREACH(rel->objects, l, obj) - efl_event_callback_del(obj, EFL_EVENT_DEL, _on_rel_obj_del, set); - *set = eina_list_remove(*set, rel); - efl_access_relation_free(rel); - return; - } - } -} - -EAPI void -efl_access_relation_set_free(Efl_Access_Relation_Set set) -{ - Efl_Access_Relation *rel; - Eina_List *l; - Eo *obj; - - EINA_LIST_FREE(set, rel) - { - EINA_LIST_FOREACH(rel->objects, l, obj) - efl_event_callback_del(obj, EFL_EVENT_DEL, _on_rel_obj_del, set); - efl_access_relation_free(rel); - } -} - -EAPI Efl_Access_Relation_Set -efl_access_relation_set_clone(const Efl_Access_Relation_Set set) -{ - Efl_Access_Relation_Set ret = NULL; - Eina_List *l; - Efl_Access_Relation *rel; - - EINA_LIST_FOREACH(set, l, rel) - { - Efl_Access_Relation *cpy = efl_access_relation_clone(rel); - ret = eina_list_append(ret, cpy); - } - - return ret; -} - -EOLIAN static Eina_Bool -_efl_access_object_relationship_append(Eo *obj EINA_UNUSED, Efl_Access_Object_Data *sd, Efl_Access_Relation_Type type, const Efl_Access_Object *relation_obj) -{ - return efl_access_relation_set_relation_append(&sd->relations, type, relation_obj); -} - EOLIAN static void -_efl_access_object_relationship_remove(Eo *obj EINA_UNUSED, Efl_Access_Object_Data *sd, Efl_Access_Relation_Type type, const Efl_Access_Object *relation_obj) +_efl_access_object_relationship_remove(Eo *obj EINA_UNUSED, Efl_Access_Object_Data *sd, Efl_Access_Relation_Type type, const Efl_Access_Object *relation) { - if (relation_obj) - efl_access_relation_set_relation_remove(&sd->relations, type, relation_obj); - else - efl_access_relation_set_relation_type_remove(&sd->relations, type); + Efl_Access_Relation *rel; + Eina_List *l; + + EINA_LIST_FOREACH(sd->relations, l, rel) + { + if (rel->type == type) + { + if (relation) + { + if (eina_list_data_find(rel->objects, relation)) + { + efl_event_callback_del((Eo *) relation, EFL_EVENT_DEL, _on_rel_obj_del, sd); + rel->objects = eina_list_remove(rel->objects, relation); + } + if (!rel->objects) + { + sd->relations = eina_list_remove(sd->relations, rel); + free(rel); + } + } + else + { + Eina_List *ll; + Eo *ro; + + EINA_LIST_FOREACH(rel->objects, ll, ro) + efl_event_callback_del(ro, EFL_EVENT_DEL, _on_rel_obj_del, sd); + sd->relations = eina_list_remove(sd->relations, rel); + free(rel); + } + return ; + } + } } EOLIAN static void _efl_access_object_relationships_clear(Eo *obj EINA_UNUSED, Efl_Access_Object_Data *sd) { - efl_access_relation_set_free(sd->relations); + efl_access_relation_set_free(sd); sd->relations = NULL; } @@ -682,13 +626,20 @@ _efl_access_object_access_type_set(Eo *obj, Efl_Access_Object_Data *pd, Efl_Acce pd->type = val; } +EOLIAN void +_efl_access_object_efl_object_invalidate(Eo *obj, Efl_Access_Object_Data *pd) +{ + efl_access_relation_set_free(pd); + + efl_invalidate(efl_super(obj, EFL_ACCESS_OBJECT_MIXIN)); +} + EOLIAN void _efl_access_object_efl_object_destructor(Eo *obj, Efl_Access_Object_Data *pd) { eina_stringshare_del(pd->name); eina_stringshare_del(pd->description); eina_stringshare_del(pd->translation_domain); - efl_access_relation_set_free(pd->relations); efl_destructor(efl_super(obj, EFL_ACCESS_OBJECT_MIXIN)); } diff --git a/src/lib/elementary/efl_access_object.eo b/src/lib/elementary/efl_access_object.eo index 5eb8b2deac..6a6cd15b99 100644 --- a/src/lib/elementary/efl_access_object.eo +++ b/src/lib/elementary/efl_access_object.eo @@ -239,8 +239,6 @@ struct Efl.Access.Relation objects: list; [[List with relation objects]] } -type Efl.Access.Relation_Set: list; [[Elementary Accessibility relation set type]] - mixin Efl.Access.Object (Efl.Interface, Efl.Object) { [[Accessibility accessible mixin]] @@ -265,13 +263,9 @@ mixin Efl.Access.Object (Efl.Interface, Efl.Object) i18n_name: string; [[Accessible name]] } } - @property relation_set @protected @beta { + relations_get @protected @beta @const { [[Gets an all relations between accessible object and other accessible objects.]] - get { - } - values { - relations: Efl.Access.Relation_Set; [[Accessible relation set]] - } + return: iterator; [[Accessible relation set]] } @property role @beta { [[The role of the object in accessibility domain.]] @@ -456,6 +450,7 @@ mixin Efl.Access.Object (Efl.Interface, Efl.Object) } implements { Efl.Object.destructor; + Efl.Object.invalidate; Efl.Object.provider_find; } events { diff --git a/src/lib/elementary/efl_access_object.h b/src/lib/elementary/efl_access_object.h index e06471ce4b..72fb57734e 100644 --- a/src/lib/elementary/efl_access_object.h +++ b/src/lib/elementary/efl_access_object.h @@ -30,41 +30,6 @@ */ EAPI void efl_access_attributes_list_free(Eina_List *list); -/** - * Frees relation. - */ -EAPI void efl_access_relation_free(Efl_Access_Relation *relation); - -/** - * Clones relation. - */ -EAPI Efl_Access_Relation * efl_access_relation_clone(const Efl_Access_Relation *relation); - -/** - * Appends relation to relation set - */ -EAPI Eina_Bool efl_access_relation_set_relation_append(Efl_Access_Relation_Set *set, Efl_Access_Relation_Type type, const Eo *rel_obj); - -/** - * Removes relation from relation set - */ -EAPI void efl_access_relation_set_relation_remove(Efl_Access_Relation_Set *set, Efl_Access_Relation_Type type, const Eo *rel_obj); - -/** - * Removes all relation from relation set of a given type - */ -EAPI void efl_access_relation_set_relation_type_remove(Efl_Access_Relation_Set *set, Efl_Access_Relation_Type type); - -/** - * Frees Efl_Access_Relation_Set - */ -EAPI void efl_access_relation_set_free(Efl_Access_Relation_Set set); - -/** - * Clones Efl_Access_Relation_Set - */ -EAPI Efl_Access_Relation_Set efl_access_relation_set_clone(const Efl_Access_Relation_Set set); - #ifdef EFL_EO_API_SUPPORT /** diff --git a/src/lib/elementary/elm_atspi_bridge.c b/src/lib/elementary/elm_atspi_bridge.c index c430f33e59..cca6176dee 100644 --- a/src/lib/elementary/elm_atspi_bridge.c +++ b/src/lib/elementary/elm_atspi_bridge.c @@ -805,9 +805,9 @@ _accessible_get_relation_set(const Eldbus_Service_Interface *iface EINA_UNUSED, Eo *rel_obj, *obj = _bridge_object_from_path(bridge, obj_path); Eldbus_Message *ret = NULL; Eldbus_Message_Iter *iter = NULL, *iter_array = NULL, *iter_array2 = NULL, *iter_struct; - Efl_Access_Relation *rel; - Eina_List *l, *l2; - Efl_Access_Relation_Set rels; + const Efl_Access_Relation *rel; + Eina_List *l; + Eina_Iterator *it; ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_OBJECT_MIXIN, msg); @@ -818,15 +818,14 @@ _accessible_get_relation_set(const Eldbus_Service_Interface *iface EINA_UNUSED, iter_array = eldbus_message_iter_container_new(iter, 'a', "(ua(so))"); EINA_SAFETY_ON_NULL_GOTO(iter_array, fail); - rels = efl_access_object_relation_set_get(obj); - - EINA_LIST_FOREACH(rels, l, rel) + it = efl_access_object_relations_get(obj); + EINA_ITERATOR_FOREACH(it, rel) { iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL); eldbus_message_iter_basic_append(iter_struct, 'u', _elm_relation_to_atspi_relation(rel->type)); iter_array2 = eldbus_message_iter_container_new(iter_struct, 'a', "(so)"); EINA_SAFETY_ON_NULL_GOTO(iter_array2, fail); - EINA_LIST_FOREACH(rel->objects, l2, rel_obj) + EINA_LIST_FOREACH(rel->objects, l, rel_obj) { _bridge_iter_object_reference_append(bridge, iter_array2, rel_obj); _bridge_object_register(bridge, rel_obj); @@ -834,7 +833,7 @@ _accessible_get_relation_set(const Eldbus_Service_Interface *iface EINA_UNUSED, eldbus_message_iter_container_close(iter_struct, iter_array2); eldbus_message_iter_container_close(iter_array, iter_struct); } - efl_access_relation_set_free(rels); + eina_iterator_free(it); eldbus_message_iter_container_close(iter, iter_array); return ret; diff --git a/src/tests/elementary/elm_test_atspi.c b/src/tests/elementary/elm_test_atspi.c index 0cb3b72ff1..1fdfa093ad 100644 --- a/src/tests/elementary/elm_test_atspi.c +++ b/src/tests/elementary/elm_test_atspi.c @@ -281,42 +281,46 @@ EFL_START_TEST (test_efl_access_object_relationship_append) { generate_app(); - Efl_Access_Relation_Set set; Efl_Access_Relation *rel, *rel_to, *rel_from; - Eina_List *l; + Eina_Iterator *it; + unsigned int i = 0; efl_access_object_relationship_append(g_btn, EFL_ACCESS_RELATION_FLOWS_TO, g_bg); efl_access_object_relationship_append(g_btn, EFL_ACCESS_RELATION_FLOWS_FROM, g_win); - set = efl_access_object_relation_set_get(g_btn); + it = efl_access_object_relations_get(g_btn); - ck_assert(set != NULL); - ck_assert(eina_list_count(set) >= 2); + ck_assert(it != NULL); rel_to = rel_from = NULL; - EINA_LIST_FOREACH(set, l, rel) + EINA_ITERATOR_FOREACH(it, rel) { + i++; + if (rel->type == EFL_ACCESS_RELATION_FLOWS_TO) rel_to = rel; if (rel->type == EFL_ACCESS_RELATION_FLOWS_FROM) rel_from = rel; } + ck_assert(i >= 2); ck_assert(rel_to != NULL); ck_assert(eina_list_data_find(rel_to->objects, g_bg) != NULL); ck_assert(rel_from != NULL); ck_assert(eina_list_data_find(rel_from->objects, g_win) != NULL); - efl_access_relation_set_free(set); + eina_iterator_free(it); /* Check if append do not procude duplicated relations */ efl_access_object_relationship_append(g_btn, EFL_ACCESS_RELATION_FLOWS_TO, g_bg); efl_access_object_relationship_append(g_btn, EFL_ACCESS_RELATION_FLOWS_FROM, g_win); - set = efl_access_object_relation_set_get(g_btn); + it = efl_access_object_relations_get(g_btn); i = 0; rel_to = rel_from = NULL; - EINA_LIST_FOREACH(set, l, rel) + EINA_ITERATOR_FOREACH(it, rel) { + i++; + if (rel->type == EFL_ACCESS_RELATION_FLOWS_TO) rel_to = rel; if (rel->type == EFL_ACCESS_RELATION_FLOWS_FROM) @@ -333,8 +337,7 @@ EFL_START_TEST (test_efl_access_object_relationship_append) rel_from->objects = eina_list_remove(rel_from->objects, g_win); ck_assert(eina_list_data_find(rel_from->objects, g_win) == NULL); - efl_access_relation_set_free(set); - + eina_iterator_free(it); } EFL_END_TEST @@ -342,43 +345,48 @@ EFL_START_TEST (test_efl_access_object_relationship_remove) { generate_app(); - Efl_Access_Relation_Set set; Efl_Access_Relation *rel, *rel_to, *rel_from; - Eina_List *l; + Eina_Iterator *it; + unsigned int i = 0; /* Test if removal of single relationship works */ efl_access_object_relationship_append(g_btn, EFL_ACCESS_RELATION_FLOWS_TO, g_bg); efl_access_object_relationship_append(g_btn, EFL_ACCESS_RELATION_FLOWS_FROM, g_win); efl_access_object_relationship_remove(g_btn, EFL_ACCESS_RELATION_FLOWS_TO, g_bg); - set = efl_access_object_relation_set_get(g_btn); + it = efl_access_object_relations_get(g_btn); - ck_assert(set != NULL); - ck_assert(eina_list_count(set) >= 1); + ck_assert(it != NULL); rel_to = rel_from = NULL; - EINA_LIST_FOREACH(set, l, rel) + EINA_ITERATOR_FOREACH(it, rel) { + i++; + if (rel->type == EFL_ACCESS_RELATION_FLOWS_TO) rel_to = rel; if (rel->type == EFL_ACCESS_RELATION_FLOWS_FROM) rel_from = rel; } + ck_assert(i >= 1); + if (rel_to) ck_assert(eina_list_data_find(rel_to->objects, g_bg) == NULL); ck_assert(rel_from != NULL); ck_assert(eina_list_data_find(rel_from->objects, g_win) != NULL); - efl_access_relation_set_free(set); + eina_iterator_free(it); /* Test if removal of type relationship works */ efl_access_object_relationship_append(g_btn, EFL_ACCESS_RELATION_FLOWS_TO, g_bg); efl_access_object_relationship_append(g_btn, EFL_ACCESS_RELATION_FLOWS_TO, g_win); efl_access_object_relationship_remove(g_btn, EFL_ACCESS_RELATION_FLOWS_TO, NULL); - set = efl_access_object_relation_set_get(g_btn); + it = efl_access_object_relations_get(g_btn); i = 0; rel_to = rel_from = NULL; - EINA_LIST_FOREACH(set, l, rel) + EINA_ITERATOR_FOREACH(it, rel) { + i++; + if (rel->type == EFL_ACCESS_RELATION_FLOWS_TO) rel_to = rel; if (rel->type == EFL_ACCESS_RELATION_FLOWS_FROM) @@ -389,17 +397,19 @@ EFL_START_TEST (test_efl_access_object_relationship_remove) ck_assert(rel_from != NULL); ck_assert(eina_list_data_find(rel_from->objects, g_win) != NULL); - efl_access_relation_set_free(set); + eina_iterator_free(it); /* Test if relationship is implicity removed when object is deleted */ efl_access_object_relationship_append(g_btn, EFL_ACCESS_RELATION_FLOWS_TO, g_bg); efl_access_object_relationship_append(g_btn, EFL_ACCESS_RELATION_FLOWS_FROM, g_bg); efl_del(g_bg); - set = efl_access_object_relation_set_get(g_btn); + it = efl_access_object_relations_get(g_btn); i = 0; rel_to = rel_from = NULL; - EINA_LIST_FOREACH(set, l, rel) + EINA_ITERATOR_FOREACH(it, rel) { + i++; + if (rel->type == EFL_ACCESS_RELATION_FLOWS_TO) rel_to = rel; if (rel->type == EFL_ACCESS_RELATION_FLOWS_FROM) @@ -409,15 +419,14 @@ EFL_START_TEST (test_efl_access_object_relationship_remove) if (rel_to) ck_assert(eina_list_data_find(rel_to->objects, g_bg) == NULL); if (rel_from) ck_assert(eina_list_data_find(rel_from->objects, g_bg) == NULL); - efl_access_relation_set_free(set); + eina_iterator_free(it); } EFL_END_TEST EFL_START_TEST (test_efl_access_object_relationships_clear) { - Efl_Access_Relation_Set set; Efl_Access_Relation *rel; - Eina_List *l; + Eina_Iterator *it; generate_app(); @@ -428,16 +437,15 @@ EFL_START_TEST (test_efl_access_object_relationships_clear) efl_access_object_relationships_clear(g_btn); - set = efl_access_object_relation_set_get(g_btn); - EINA_LIST_FOREACH(set, l, rel) + it = efl_access_object_relations_get(g_btn); + EINA_ITERATOR_FOREACH(it, rel) { ck_assert(!((rel->type == EFL_ACCESS_RELATION_FLOWS_TO) && eina_list_data_find(rel->objects, g_bg))); ck_assert(!((rel->type == EFL_ACCESS_RELATION_FLOWS_FROM) && eina_list_data_find(rel->objects, g_bg))); ck_assert(!((rel->type == EFL_ACCESS_RELATION_FLOWS_TO) && eina_list_data_find(rel->objects, g_win))); ck_assert(!((rel->type == EFL_ACCESS_RELATION_FLOWS_FROM) && eina_list_data_find(rel->objects, g_win))); } - - efl_access_relation_set_free(set); + eina_iterator_free(it); } EFL_END_TEST