furrymyad pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=bac07e79cea59b1859e23d83028763e3f38c087a
commit bac07e79cea59b1859e23d83028763e3f38c087a Author: Vitalii Vorobiov <vi.vorob...@samsung.com> Date: Mon Feb 2 11:14:45 2015 +0200 Edje: edje_edit - abort Recursive Reference in edje_edit_part_source_set It is unable to do recursive reference such as: > Having group A with GROUP part that has group B as source. > Having group B with GROUP part that has group A as source. Here we have a loop that is not allowed by edje_cc, so edje_edit also need to check this case. @fix --- src/lib/edje/Edje_Edit.h | 4 ++++ src/lib/edje/edje_edit.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/lib/edje/Edje_Edit.h b/src/lib/edje/Edje_Edit.h index 053a511..12db53b 100644 --- a/src/lib/edje/Edje_Edit.h +++ b/src/lib/edje/Edje_Edit.h @@ -1234,6 +1234,10 @@ EAPI const char * edje_edit_part_source_get(Evas_Object *obj, const char *part); /** Set the source of part. * + * If setting source of the part will lead to recursive reference + * (when A source to B, and B is going to be source to A because of this funciton), + * then it will return EINA_FALSE. + * * @param obj Object being edited. * @param part Part to set the source of. * @param source Value for the source parameter. diff --git a/src/lib/edje/edje_edit.c b/src/lib/edje/edje_edit.c index 55a262d..d19a19a 100644 --- a/src/lib/edje/edje_edit.c +++ b/src/lib/edje/edje_edit.c @@ -3893,17 +3893,58 @@ edje_edit_part_source_get(Evas_Object *obj, const char *part) return eina_stringshare_add(rp->part->source); } +static Eina_Bool +_check_recursive_reference(Edje *ed, const char *source, Eina_List *group_path, Edje_Part *part) +{ + unsigned int i; + char *data; + Edje_Part_Collection_Directory_Entry *e; + Eina_List *l; + Eina_Bool no_ref = EINA_TRUE; + + if (!source) return EINA_TRUE; + + e = eina_hash_find(ed->file->collection, source); + + /* Go through every part to find parts with type GROUP */ + for (i = 0; i < e->ref->parts_count; ++i) + { + if ((e->ref->parts[i]->type == EDJE_PART_TYPE_GROUP) && + (e->ref->parts[i]->source)) + { + /* Make sure that this group isn't already in the tree of parents */ + EINA_LIST_FOREACH(group_path, l, data) + { + if (data == e->ref->parts[i]->source) + return EINA_FALSE; + } + group_path = eina_list_append(group_path, source); + no_ref &= _check_recursive_reference(ed, e->ref->parts[i]->source, group_path, part); + } + + /* We did a loop here... this part doesn't have source yet, + but if it will set, it'll be a recursive reference. */ + if (e->ref->parts[i] == part) return EINA_FALSE; + } + return no_ref; +} + EAPI Eina_Bool edje_edit_part_source_set(Evas_Object *obj, const char *part, const char *source) { GET_RP_OR_RETURN(EINA_FALSE); Evas_Object *child_obj; + Eina_List *group_path = NULL; //printf("Set source for part: %s [source: %s]\n", part, source); switch (rp->part->type) { case EDJE_PART_TYPE_GROUP: + /* find source group */ + if (!_check_recursive_reference(ed, source, group_path, rp->part)) + return EINA_FALSE; + if ((rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object)) { _edje_real_part_swallow_clear(ed, rp); --