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
This commit is contained in:
Vitalii Vorobiov 2015-02-02 11:14:45 +02:00
parent 45aba1343e
commit bac07e79ce
2 changed files with 45 additions and 0 deletions

View File

@ -1233,6 +1233,10 @@ EAPI Eina_Bool edje_edit_part_clip_to_set(Evas_Object *obj, const char *part, co
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.

View File

@ -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);