summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitalii Vorobiov <vi.vorobiov@samsung.com>2015-02-02 11:14:45 +0200
committerVitalii Vorobiov <vi.vorobiov@samsung.com>2015-02-02 11:37:20 +0200
commitbac07e79cea59b1859e23d83028763e3f38c087a (patch)
tree585baad626ee7b2baa72810e8776e5dff9e63c80
parent45aba1343ea30d96e8c4a1b2d9194a2cf65c457f (diff)
downloadefl-bac07e79cea59b1859e23d83028763e3f38c087a.tar.gz
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
-rw-r--r--src/lib/edje/Edje_Edit.h4
-rw-r--r--src/lib/edje/edje_edit.c41
2 files changed, 45 insertions, 0 deletions
diff --git a/src/lib/edje/Edje_Edit.h b/src/lib/edje/Edje_Edit.h
index 053a511b78..12db53b4c0 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 55a262dd31..d19a19aa0f 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);