diff --git a/src/lib/elementary/efl_ui_collection.c b/src/lib/elementary/efl_ui_collection.c index eef694e3e0..a3ad0daf57 100644 --- a/src/lib/elementary/efl_ui_collection.c +++ b/src/lib/elementary/efl_ui_collection.c @@ -700,6 +700,53 @@ update_pos_man(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd, Efl_Gfx_Entity * efl_ui_position_manager_entity_item_added(pd->pos_man, id, subobj); } +static inline Efl_Ui_Item* +fetch_rep_parent(Eina_List *lst) +{ + if (!lst) + return NULL; + + Efl_Ui_Item *it = eina_list_data_get(lst); + + return efl_ui_item_parent_get(it); +} + +static Eina_Bool +check_group_integrity(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd, Efl_Gfx_Entity *subobj) +{ + Eina_List *carrier_list = eina_list_data_find_list(pd->items, subobj), *prev_lst; + Efl_Ui_Item *next, *prev, *carrier; + + prev_lst = eina_list_prev(carrier_list); + next = fetch_rep_parent(eina_list_next(carrier_list)); + prev = fetch_rep_parent(prev_lst); + carrier = fetch_rep_parent(carrier_list); + + if (next && next == prev && carrier != prev) + { + //a item got inserted into the middle of one group, but does not have the correct group header, that is a bug + ERR("Inserting a item with the wrong group into another group(%p,%p,%p)", prev, carrier, next); + unregister_item(obj, pd, subobj); + return EINA_FALSE; + } + + if (prev_lst && eina_list_data_get(prev_lst) == next && carrier != next) + { + //a item got inserted between group header and group children, also a error + ERR("Inserting a item between group header, and group elements(%p,%p,%p)", prev_lst, eina_list_data_get(prev_lst), next); + unregister_item(obj, pd, subobj); + return EINA_FALSE; + } + if (!next && !prev && carrier && prev_lst && eina_list_data_get(prev_lst) != carrier) + { + ERR("Tried to insert a item with group, outside its group(%p,%p,%p)", next, prev, carrier); + unregister_item(obj, pd, subobj); + return EINA_FALSE; + } + + return EINA_TRUE; +} + EOLIAN static Eina_Bool _efl_ui_collection_efl_pack_pack_clear(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd) { @@ -779,6 +826,7 @@ _efl_ui_collection_efl_pack_linear_pack_before(Eo *obj, Efl_Ui_Collection_Data * if (!register_item(obj, pd, subobj)) return EINA_FALSE; pd->items = eina_list_prepend_relative_list(pd->items, subobj, subobj_list); + if (!check_group_integrity(obj, pd, subobj)) return EINA_FALSE; update_pos_man(obj, pd, subobj); return EINA_TRUE; } @@ -792,6 +840,7 @@ _efl_ui_collection_efl_pack_linear_pack_after(Eo *obj, Efl_Ui_Collection_Data *p if (!register_item(obj, pd, subobj)) return EINA_FALSE; pd->items = eina_list_append_relative_list(pd->items, subobj, subobj_list); + if (!check_group_integrity(obj, pd, subobj)) return EINA_FALSE; update_pos_man(obj, pd, subobj); return EINA_TRUE; } @@ -814,6 +863,7 @@ _efl_ui_collection_efl_pack_linear_pack_at(Eo *obj, Efl_Ui_Collection_Data *pd, pd->items = eina_list_append(pd->items, subobj); else pd->items = eina_list_prepend(pd->items, subobj); + if (!check_group_integrity(obj, pd, subobj)) return EINA_FALSE; update_pos_man(obj, pd, subobj); return EINA_TRUE; } diff --git a/src/tests/elementary/efl_ui_test_collection_common.c b/src/tests/elementary/efl_ui_test_collection_common.c index 7be3c7c532..5bd2c5cd55 100644 --- a/src/tests/elementary/efl_ui_test_collection_common.c +++ b/src/tests/elementary/efl_ui_test_collection_common.c @@ -22,6 +22,42 @@ fill_items(const Efl_Class *klass) } } -void efl_ui_test_item_container_common_add(TCase *tc EINA_UNUSED) +EFL_START_TEST(finalizer_group_middle_insert) { + Efl_Ui_Group_Item *group_item = efl_add(EFL_UI_GROUP_ITEM_CLASS, item_container); + efl_pack_end(item_container, group_item); + Efl_Ui_Group_Item *i1 = efl_add(EFL_UI_LIST_DEFAULT_ITEM_CLASS, item_container); + efl_pack_end(group_item, i1); + Efl_Ui_Group_Item *i2 = efl_add(EFL_UI_LIST_DEFAULT_ITEM_CLASS, item_container); + efl_pack_end(group_item, i2); + Efl_Ui_Group_Item *e = efl_add(EFL_UI_LIST_DEFAULT_ITEM_CLASS, item_container); + + EXPECT_ERROR_START; + efl_pack_after(item_container, e, group_item); + EXPECT_ERROR_END; + EXPECT_ERROR_START; + efl_pack_after(item_container, e, i1); + EXPECT_ERROR_END; + + EXPECT_ERROR_START; + efl_pack_before(item_container, e, i1); + EXPECT_ERROR_END; + EXPECT_ERROR_START; + efl_pack_before(item_container, e, i2); + EXPECT_ERROR_END; + + EXPECT_ERROR_START; + efl_pack_at(item_container, e, 1); + EXPECT_ERROR_END; + EXPECT_ERROR_START; + efl_pack_at(item_container, e, 2); + EXPECT_ERROR_END; + + efl_del(item_container); +} +EFL_END_TEST + +void efl_ui_test_item_container_common_add(TCase *tc) +{ + tcase_add_test(tc, finalizer_group_middle_insert); }