1 /*
2  * TODO
3  * -----------------------------------------------------------------
4  * Add LUA Support :)
5  * Remove images/fonts
6  * Clean the saving routines
7  *
8  */
9 
10 #define _EDJE_EDIT_EO_CLASS_TYPE
11 #define EFL_CANVAS_GROUP_PROTECTED
12 
13 #include "edje_private.h"
14 
15 #include "canvas/evas_canvas_eo.h"
16 
17 #define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT
18 #include "Edje_Edit.h"
19 
20 #include <Eo.h>
21 
22 #include "../../static_libs/buildsystem/buildsystem.h"
23 
24 #ifdef MY_CLASS
25 # undef MY_CLASS
26 #endif
27 
28 #define MY_CLASS EDJE_EDIT_CLASS
29 
30 EAPI Eina_Error EDJE_EDIT_ERROR_GROUP_CURRENTLY_USED = 0;
31 EAPI Eina_Error EDJE_EDIT_ERROR_GROUP_REFERENCED = 0;
32 EAPI Eina_Error EDJE_EDIT_ERROR_GROUP_DOES_NOT_EXIST = 0;
33 
34 /* Get eed(Edje_Edit*) from obj(Evas_Object*) */
35 #define GET_EED_OR_RETURN(RET)            \
36   Edje_Edit *eed;                         \
37   if (!efl_isa(obj, MY_CLASS))             \
38     return RET;                           \
39   eed = efl_data_scope_get(obj, MY_CLASS); \
40   if (!eed) return RET;
41 
42 /* Get ed(Edje*) from obj(Evas_Object*) */
43 #define GET_ED_OR_RETURN(RET)          \
44   Edje *ed;                            \
45   if (!efl_isa(obj, EFL_CANVAS_LAYOUT_CLASS)) \
46     return RET;                        \
47   ed = efl_data_scope_get(obj, EFL_CANVAS_LAYOUT_CLASS);
48 
49 /* Get rp(Edje_Real_Part*) from obj(Evas_Object*) and part(char*) */
50 #define GET_RP_OR_RETURN(RET)         \
51   GET_ED_OR_RETURN(RET)               \
52   Edje_Real_Part *rp;                 \
53   rp = _edje_real_part_get(ed, part); \
54   if (!rp) return RET;
55 
56 /* Get pd(Edje_Part_Description*) from obj(Evas_Object*), part(char*) and state (char*) */
57 #define GET_PD_OR_RETURN(RET)                                       \
58   GET_EED_OR_RETURN(RET)                                            \
59   GET_ED_OR_RETURN(RET)                                             \
60   Edje_Real_Part *rp;                                               \
61   Edje_Part_Description_Common *pd;                                 \
62   rp = _edje_real_part_get(ed, part);                               \
63   if (!rp) return RET;                                              \
64   pd = _edje_part_description_find_byname(eed, part, state, value); \
65   if (!pd) return RET;
66 
67 /* Get epr(Edje_Program*) from obj(Evas_Object*) and prog(char*)*/
68 #define GET_EPR_OR_RETURN(RET)               \
69   Edje_Program *epr;                         \
70   if (!efl_isa(obj, MY_CLASS))                \
71     return RET;                              \
72   epr = _edje_program_get_byname(obj, prog); \
73   if (!epr) return RET;
74 
75 static void *
_alloc(size_t size)76 _alloc(size_t size)
77 {
78    void *mem;
79 
80    mem = calloc(1, size);
81    if (mem) return mem;
82    ERR("Edje_Edit: Error. memory allocation of %i bytes failed. %s",
83        (int)size, strerror(errno));
84    return NULL;
85 }
86 
87 /*************/
88 /* INTERNALS */
89 /*************/
90 
91 /* Edje_Edit smart! Overloads the edje one adding some more control stuff */
92 
93 typedef struct _Edje_Edit Edje_Edit;
94 struct _Edje_Edit
95 {
96    Edje      *base;
97 
98    void      *bytecode;
99    int        bytecode_size;
100 
101    char      *embryo_source;
102    char      *embryo_processed;
103    Eina_Hash *program_scripts;
104 
105    Eina_List *errors;
106 
107    Eina_Bool  bytecode_dirty : 1;
108    Eina_Bool  embryo_source_dirty : 1;
109    Eina_Bool  all_dirty : 1;
110    Eina_Bool  script_need_recompile : 1;
111 };
112 
113 typedef struct _Program_Script Program_Script;
114 struct _Program_Script
115 {
116    int       id;
117    char     *code;
118    char     *processed;
119    Eina_Bool dirty : 1;
120    Eina_Bool delete_me : 1;
121 };
122 
123 static Eina_Bool _edje_edit_edje_file_save(Eet_File *eetf, Edje_File *ef);
124 
125 static void
_edje_edit_data_clean(Edje_Edit * eed)126 _edje_edit_data_clean(Edje_Edit *eed)
127 {
128    Edje_Edit_Script_Error *se;
129 
130    free(eed->bytecode);
131    free(eed->embryo_source);
132    free(eed->embryo_processed);
133 
134    if (eed->program_scripts)
135      eina_hash_free(eed->program_scripts);
136 
137    EINA_LIST_FREE(eed->errors, se)
138      {
139         eina_stringshare_del(se->program_name);
140         eina_stringshare_del(se->error_str);
141         free(se);
142      }
143 
144    eed->bytecode = NULL;
145    eed->embryo_source = NULL;
146    eed->embryo_processed = NULL;
147    eed->program_scripts = NULL;
148    eed->bytecode_size = 0;
149    eed->bytecode_dirty = EINA_FALSE;
150    eed->embryo_source_dirty = EINA_FALSE;
151    eed->all_dirty = EINA_FALSE;
152    eed->script_need_recompile = EINA_FALSE;
153 }
154 
155 EOLIAN static void
_edje_edit_efl_canvas_group_group_del(Eo * obj,Edje_Edit * eed)156 _edje_edit_efl_canvas_group_group_del(Eo *obj, Edje_Edit *eed)
157 {
158    _edje_edit_data_clean(eed);
159 
160    efl_canvas_group_del(efl_super(obj, MY_CLASS));
161 }
162 
163 static void
_edje_edit_program_script_free(Program_Script * ps)164 _edje_edit_program_script_free(Program_Script *ps)
165 {
166    free(ps->code);
167    free(ps->processed);
168    free(ps);
169 }
170 
171 static Eet_File *
_edje_edit_eet_open(Edje * ed,Eet_File_Mode mode)172 _edje_edit_eet_open(Edje *ed, Eet_File_Mode mode)
173 {
174    Eet_File *eetf;
175 
176    switch (mode)
177      {
178       case EET_FILE_MODE_INVALID:
179          return NULL;
180       case EET_FILE_MODE_READ:
181          return ed->file->ef;
182       case EET_FILE_MODE_WRITE:
183       case EET_FILE_MODE_READ_WRITE:
184          eetf = eet_open(ed->path, mode);
185          if (!eetf)
186            ERR("Unable to open \"%s\" for writing output", ed->path);
187          return eetf;
188      }
189    return NULL;
190 }
191 
192 static void
_edje_edit_eet_close(Eet_File * ef)193 _edje_edit_eet_close(Eet_File *ef)
194 {
195    Eet_File_Mode mode = eet_mode_get(ef);
196    if (mode != EET_FILE_MODE_READ)
197      eet_close(ef);
198 }
199 
200 static Eina_Bool
_load_scripts(Eo * obj,Edje_Edit * eed)201 _load_scripts(Eo *obj, Edje_Edit *eed)
202 {
203    Eet_File *ef;
204    char **keys, buf[64];
205    int count, i;
206    int len = strlen("edje/scripts/embryo/source/");
207 
208    GET_ED_OR_RETURN(EINA_FALSE);
209 
210    eed->program_scripts = eina_hash_int32_new((Eina_Free_Cb)_edje_edit_program_script_free);
211 
212    ef = _edje_edit_eet_open(ed, EET_FILE_MODE_READ);
213 
214    snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%i",
215             eed->base->collection->id);
216    eed->embryo_source = eet_read(ef, buf, &count);
217 
218    snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%i/*",
219             eed->base->collection->id);
220    keys = eet_list(ef, buf, &count);
221    if (keys)
222      {
223         for (i = 0; i < count; i++)
224           {
225              Program_Script *ps;
226              int size;
227 
228              ps = calloc(1, sizeof(Program_Script));
229 
230              sscanf(keys[i] + len, "%*i/%i", &ps->id);
231              ps->code = eet_read(ef, keys[i], &size);
232              eina_hash_add(eed->program_scripts, &ps->id, ps);
233           }
234         free(keys);
235      }
236    _edje_edit_eet_close(ef);
237 
238    return EINA_TRUE;
239 }
240 
241 EOLIAN static Eina_Error
_edje_edit_efl_file_load(Eo * obj,Edje_Edit * eed)242 _edje_edit_efl_file_load(Eo *obj, Edje_Edit *eed)
243 {
244    Eina_Error err;
245 
246    if (efl_file_loaded_get(obj)) return 0;
247 
248    _edje_edit_data_clean(eed);
249 
250    err = efl_file_load(efl_super(obj, MY_CLASS));
251    if (err) return err;
252    /* TODO and maybes:
253     *  * The whole point of this thing is keep track of stuff such as
254     *    strings to free and who knows what, so we need to take care
255     *    of those if the file/group changes.
256     *  * Maybe have the possibility to open just files, not always with
257     *    a group given.
258     *  * A way to skip the cache? Could help avoid some issues when editing
259     *    a group being used by the application in some other way, or multiple
260     *    opens of the same file.
261     *  * Here we probably want to allow opening groups with broken references
262     *    (GROUP parts or BOX/TABLE items pointing to non-existent/renamed
263     *    groups).
264     *  P.S. don't forget about mmap version below
265     */
266    if (!_load_scripts(obj, eed))
267      return EFL_GFX_IMAGE_LOAD_ERROR_GENERIC;
268 
269    return 0;
270 }
271 
272 EOLIAN static void
_edje_edit_efl_file_unload(Eo * obj,Edje_Edit * eed)273 _edje_edit_efl_file_unload(Eo *obj, Edje_Edit *eed)
274 {
275    efl_file_unload(efl_super(obj, MY_CLASS));
276    _edje_edit_data_clean(eed);
277 }
278 
279 EAPI Evas_Object *
edje_edit_object_add(Evas * evas)280 edje_edit_object_add(Evas *evas)
281 {
282    evas = evas_find(evas);
283    EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(evas, EVAS_CANVAS_CLASS), NULL);
284    return efl_add(MY_CLASS, evas, efl_canvas_object_legacy_ctor(efl_added));
285 }
286 
287 EOLIAN static Eo *
_edje_edit_efl_object_constructor(Eo * obj,Edje_Edit * eed)288 _edje_edit_efl_object_constructor(Eo *obj, Edje_Edit *eed)
289 {
290    eed->base = efl_data_ref(obj, EFL_CANVAS_LAYOUT_CLASS);
291 
292    return efl_constructor(efl_super(obj, MY_CLASS));
293 }
294 
295 EOLIAN static void
_edje_edit_efl_object_destructor(Eo * obj,Edje_Edit * class_data EINA_UNUSED)296 _edje_edit_efl_object_destructor(Eo *obj, Edje_Edit *class_data EINA_UNUSED)
297 {
298    efl_destructor(efl_super(obj, MY_CLASS));
299    efl_data_unref(obj, class_data);
300 }
301 
302 /* End of Edje_Edit smart stuff */
303 
304 static Edje_Part_Description_Common *
_edje_part_description_find_byname(Edje_Edit * eed,const char * part,const char * state,double value)305 _edje_part_description_find_byname(Edje_Edit *eed, const char *part, const char *state, double value)
306 {
307    Edje_Real_Part *rp;
308    Edje_Part_Description_Common *pd;
309 
310    if (!eed || !part || !state) return NULL;
311 
312    rp = _edje_real_part_get(eed->base, part);
313    if (!rp) return NULL;
314 
315    pd = _edje_part_description_find(eed->base, rp, state, value, EINA_FALSE);
316 
317    return pd;
318 }
319 
320 static int
_edje_vector_id_find(Edje_Edit * eed,const char * vector_name)321 _edje_vector_id_find(Edje_Edit *eed, const char *vector_name)
322 {
323    unsigned int i;
324 
325    if (!eed->base->file) return -1;
326    if (!eed->base->file->image_dir) return -1;
327 
328    //printf("SEARCH IMAGE %s\n", vector_name);
329 
330    for (i = 0; i < eed->base->file->image_dir->vectors_count; ++i)
331      if (eed->base->file->image_dir->vectors[i].entry
332          && !strcmp(vector_name, eed->base->file->image_dir->vectors[i].entry))
333        return i;
334 
335    return -1;
336 }
337 
338 static int
_edje_image_id_find(Edje_Edit * eed,const char * image_name)339 _edje_image_id_find(Edje_Edit *eed, const char *image_name)
340 {
341    unsigned int i;
342 
343    if (!eed->base->file) return -1;
344    if (!eed->base->file->image_dir) return -1;
345 
346    //printf("SEARCH IMAGE %s\n", image_name);
347 
348    for (i = 0; i < eed->base->file->image_dir->entries_count; ++i)
349      if (eed->base->file->image_dir->entries[i].entry
350          && !strcmp(image_name, eed->base->file->image_dir->entries[i].entry))
351        return i;
352 
353    return -1;
354 }
355 
356 static int
_edje_set_id_find(Edje_Edit * eed,const char * set_name)357 _edje_set_id_find(Edje_Edit *eed, const char *set_name)
358 {
359    unsigned int i;
360 
361    if (!eed->base->file) return -1;
362    if (!eed->base->file->image_dir) return -1;
363 
364    for (i = 0; i < eed->base->file->image_dir->sets_count; ++i)
365      if (eed->base->file->image_dir->sets[i].name
366          && !strcmp(set_name, eed->base->file->image_dir->sets[i].name))
367        return i;
368 
369    return -1;
370 }
371 
372 static const char *
_edje_image_name_find(Edje_Edit * eed,int image_id)373 _edje_image_name_find(Edje_Edit *eed, int image_id)
374 {
375    if (!eed->base->file) return NULL;
376    if (!eed->base->file->image_dir) return NULL;
377 
378    /* Special case for external image */
379    if (image_id < 0) image_id = -image_id - 1;
380 
381    //printf("SEARCH IMAGE ID %d\n", image_id);
382    if ((unsigned int)image_id >= eed->base->file->image_dir->entries_count)
383      return NULL;
384    return eed->base->file->image_dir->entries[image_id].entry;
385 }
386 
387 static const char *
_edje_set_name_find(Edje_Edit * eed,int set_id)388 _edje_set_name_find(Edje_Edit *eed, int set_id)
389 {
390    if (!eed->base->file) return NULL;
391    if (!eed->base->file->image_dir) return NULL;
392 
393    if ((unsigned int)set_id >= eed->base->file->image_dir->sets_count)
394      return NULL;
395    return eed->base->file->image_dir->sets[set_id].name;
396 }
397 
398 static const char *
_edje_vector_name_find(Edje_Edit * eed,int vector_id)399 _edje_vector_name_find(Edje_Edit *eed, int vector_id)
400 {
401    if (!eed->base->file) return NULL;
402    if (!eed->base->file->image_dir) return NULL;
403 
404    if ((unsigned int)vector_id >= eed->base->file->image_dir->vectors_count)
405      return NULL;
406    return eed->base->file->image_dir->vectors[vector_id].entry;
407 }
408 
409 static void
_edje_real_part_free(Edje * ed,Edje_Real_Part * rp)410 _edje_real_part_free(Edje *ed, Edje_Real_Part *rp)
411 {
412    if (!rp) return;
413 
414    if (rp->object)
415      {
416         _edje_callbacks_del(rp->object, ed);
417         evas_object_del(rp->object);
418      }
419 
420    if ((rp->type == EDJE_RP_TYPE_SWALLOW) && (rp->typedata.swallow)
421        && (rp->typedata.swallow->swallowed_object))
422      {
423         efl_parent_set(rp->typedata.swallow->swallowed_object, evas_object_evas_get(ed->obj));
424         evas_object_smart_member_del(rp->typedata.swallow->swallowed_object);
425         evas_object_event_callback_del(rp->typedata.swallow->swallowed_object,
426                                        EVAS_CALLBACK_FREE, _edje_object_part_swallow_free_cb);
427         evas_object_clip_unset(rp->typedata.swallow->swallowed_object);
428         evas_object_data_del(rp->typedata.swallow->swallowed_object,
429                              "\377 edje.swallowing_part");
430         if (rp->part->mouse_events)
431           _edje_callbacks_del(rp->typedata.swallow->swallowed_object, ed);
432 
433         if (rp->part->type == EDJE_PART_TYPE_GROUP ||
434             rp->part->type == EDJE_PART_TYPE_EXTERNAL)
435           evas_object_del(rp->typedata.swallow->swallowed_object);
436 
437         rp->typedata.swallow->swallowed_object = NULL;
438      }
439 
440    if ((rp->type == EDJE_RP_TYPE_TEXT) && (rp->typedata.text) &&
441        (rp->typedata.text->text)) eina_stringshare_del(rp->typedata.text->text);
442    if ((rp->type == EDJE_RP_TYPE_TEXT) && (rp->typedata.text) &&
443        (rp->typedata.text->font)) eina_stringshare_del(rp->typedata.text->font);
444    if ((rp->type == EDJE_RP_TYPE_TEXT) && (rp->typedata.text) &&
445        (rp->typedata.text->cache.in_str)) eina_stringshare_del(rp->typedata.text->cache.in_str);
446    if ((rp->type == EDJE_RP_TYPE_TEXT) && (rp->typedata.text) &&
447        (rp->typedata.text->cache.out_str)) eina_stringshare_del(rp->typedata.text->cache.out_str);
448 
449    if (rp->custom)
450      {
451         _edje_collection_free_part_description_clean(rp->part->type, rp->custom->description, 0);
452         if (rp->custom) free(rp->custom->set);
453         eina_mempool_free(_edje_real_part_state_mp, rp->custom);
454         rp->custom = NULL;
455      }
456 
457    if (rp->drag)
458      {
459         free(rp->drag);
460         rp->drag = NULL;
461      }
462 
463    if (rp->param2) free(rp->param2->set);
464    eina_mempool_free(_edje_real_part_state_mp, rp->param2);
465 
466    _edje_unref(ed);
467    eina_mempool_free(_edje_real_part_mp, rp);
468 }
469 
470 static Eina_Bool
_edje_edit_file_import(Edje * ed,const char * path,const char * entry,int compress)471 _edje_edit_file_import(Edje *ed, const char *path, const char *entry, int compress)
472 {
473    Eina_File *f;
474    Eet_File *eetf = NULL;
475    void *fdata = NULL;
476    long fsize = 0;
477 
478    /* Read data from file */
479    f = eina_file_open(path, 0);
480    if (!f)
481      {
482         ERR("Unable to open file \"%s\"", path);
483         return EINA_FALSE;
484      }
485 
486    fsize = eina_file_size_get(f);
487    fdata = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
488    if (!fdata)
489      {
490         ERR("Unable to map file \"%s\"", path);
491         goto on_error;
492      }
493 
494    /* Write file data to edje file */
495    eetf = _edje_edit_eet_open(ed, EET_FILE_MODE_READ_WRITE);
496    if (!eetf)
497      goto on_error;
498 
499    if (eet_write(eetf, entry, fdata, fsize, compress) <= 0)
500      {
501         ERR("Unable to write \"%s\" as \"%s\" part entry",
502             path, entry);
503         goto on_error;
504      }
505 
506    /* write the edje_file */
507    if (!_edje_edit_edje_file_save(eetf, ed->file))
508      goto on_error;
509 
510    _edje_edit_eet_close(eetf);
511 
512    eina_file_map_free(f, fdata);
513    eina_file_close(f); // close matching open OK
514 
515    return EINA_TRUE;
516 
517 on_error:
518    if (eetf) _edje_edit_eet_close(eetf);
519    eina_file_map_free(f, fdata);
520    eina_file_close(f); // close matching open OK
521 
522    return EINA_FALSE;
523 }
524 
525 static Eina_Bool
_edje_import_image_file(Edje * ed,const char * path,int id)526 _edje_import_image_file(Edje *ed, const char *path, int id)
527 {
528    char entry[PATH_MAX];
529    Evas_Object *im;
530    Eet_File *eetf;
531    void *im_data;
532    int im_w, im_h;
533    int im_alpha;
534    int bytes;
535 
536    /* Try to load the file */
537    im = evas_object_image_add(ed->base.evas);
538    if (!im) return EINA_FALSE;
539 
540    evas_object_image_file_set(im, path, NULL);
541    if (evas_object_image_load_error_get(im) != EVAS_LOAD_ERROR_NONE)
542      {
543         ERR("Edje_Edit: unable to load image \"%s\"."
544             "Missing PNG or JPEG loader modules for Evas or "
545             "file does not exist, or is not readable.", path);
546         evas_object_del(im);
547         im = NULL;
548         return EINA_FALSE;
549      }
550 
551    /* Write the loaded image to the edje file */
552 
553    evas_object_image_size_get(im, &im_w, &im_h);
554    im_alpha = evas_object_image_alpha_get(im);
555    im_data = evas_object_image_data_get(im, 0);
556    if ((!im_data) || !(im_w > 0) || !(im_h > 0))
557      {
558         evas_object_del(im);
559         return EINA_FALSE;
560      }
561 
562    /* open the eet file */
563    eetf = _edje_edit_eet_open(ed, EET_FILE_MODE_READ_WRITE);
564    if (!eetf)
565      {
566         evas_object_del(im);
567         return EINA_FALSE;
568      }
569 
570    snprintf(entry, sizeof(entry), "edje/images/%i", id);
571 
572    /* write the image data */
573    bytes = eet_data_image_write(eetf, entry,
574                                 im_data, im_w, im_h,
575                                 im_alpha,
576                                 0, 100, 1);
577    if (bytes <= 0)
578      {
579         ERR("Unable to write image part \"%s\" part entry to %s",
580             entry, ed->path);
581         _edje_edit_eet_close(eetf);
582         evas_object_del(im);
583         return EINA_FALSE;
584      }
585 
586    evas_object_del(im);
587 
588    /* write the edje_file */
589    if (!_edje_edit_edje_file_save(eetf, ed->file))
590      {
591         eet_delete(eetf, entry);
592         _edje_edit_eet_close(eetf);
593         return EINA_FALSE;
594      }
595 
596    _edje_edit_eet_close(eetf);
597    return EINA_TRUE;
598 }
599 
600 static int
_edje_part_id_find(Edje * ed,const char * part)601 _edje_part_id_find(Edje *ed, const char *part)
602 {
603    unsigned int id;
604 
605    for (id = 0; id < ed->table_parts_size; id++)
606      {
607         Edje_Real_Part *rp = ed->table_parts[id];
608 
609         if (!strcmp(rp->part->name, part))
610           return id;
611      }
612    return -1;
613 }
614 
615 static const char *
_edje_part_name_find(Edje * ed,int id)616 _edje_part_name_find(Edje *ed, int id)
617 {
618    unsigned int i;
619    if (id < 0) return NULL;
620 
621    for (i = 0; i < ed->table_parts_size; i++)
622      {
623         Edje_Real_Part *rp = ed->table_parts[i];
624         if (rp->part->id == id)
625           return rp->part->name;
626      }
627    return NULL;
628 }
629 
630 static void
_edje_part_description_id_set(int type,Edje_Part_Description_Common * c,int old_id,int new_id)631 _edje_part_description_id_set(int type, Edje_Part_Description_Common *c, int old_id, int new_id)
632 {
633    if (c->rel1.id_x == old_id) c->rel1.id_x = new_id;
634    if (c->rel1.id_y == old_id) c->rel1.id_y = new_id;
635    if (c->rel2.id_x == old_id) c->rel2.id_x = new_id;
636    if (c->rel2.id_y == old_id) c->rel2.id_y = new_id;
637    if (c->clip_to_id == old_id) c->clip_to_id = new_id;
638 
639    if (type == EDJE_PART_TYPE_TEXT
640        || type == EDJE_PART_TYPE_TEXTBLOCK)
641      {
642         Edje_Part_Description_Text *t;
643 
644         t = (Edje_Part_Description_Text *)c;
645 
646         if (t->text.id_source == old_id) t->text.id_source = new_id;
647         if (t->text.id_text_source == old_id) t->text.id_text_source = new_id;
648      }
649 }
650 
651 static void
_edje_part_program_id_set(Edje_Program * epr,int old_id,int new_id)652 _edje_part_program_id_set(Edje_Program *epr, int old_id, int new_id)
653 {
654    Edje_Program_Target *pt;
655    Eina_List *ll, *l_next;
656 
657    if (epr->action != EDJE_ACTION_TYPE_STATE_SET)
658      return;
659 
660    EINA_LIST_FOREACH_SAFE(epr->targets, ll, l_next, pt)
661      {
662         if (pt->id == old_id)
663           {
664              if (new_id == -1)
665                epr->targets = eina_list_remove_list(epr->targets, ll);
666              else
667                pt->id = new_id;
668           }
669      }
670 }
671 
672 static void
_edje_part_id_set(Edje * ed,Edje_Real_Part * rp,int new_id)673 _edje_part_id_set(Edje *ed, Edje_Real_Part *rp, int new_id)
674 {
675    /* This function change the id of a given real_part.
676     * All the depedency will be updated too.
677     * Also the table_parts is updated, and the current *rp in the table
678     * is lost.
679     * If new Id = -1 then all the depencies will be deleted
680     */
681    Edje_Part *part;
682    unsigned int j;
683    int old_id;
684 
685    part = rp->part;
686 
687    if (!part) return;
688    //printf("CHANGE ID OF PART %s TO %d\n", part->name, new_id);
689 
690    if (!ed || new_id < -1) return;
691 
692    if (part->id == new_id) return;
693 
694    old_id = part->id;
695    part->id = new_id;
696 
697    /* Fix all the dependecies in all parts... */
698    for (j = 0; j < ed->collection->parts_count; ++j)
699      {
700         Edje_Part *p;
701         unsigned int k;
702 
703         p = ed->collection->parts[j];
704 
705         //printf("   search id: %d in %s\n", old_id, p->name);
706         if (p->clip_to_id == old_id) p->clip_to_id = new_id;
707         if (p->dragable.confine_id == old_id) p->dragable.confine_id = new_id;
708 
709         /* ...in default description */
710         _edje_part_description_id_set(p->type, p->default_desc, old_id, new_id);
711 
712         /* ...and in all other descriptions */
713         for (k = 0; k < p->other.desc_count; ++k)
714           _edje_part_description_id_set(p->type, p->other.desc[k], old_id, new_id);
715      }
716 
717    /*...and also in programs targets */
718 #define EDJE_EDIT_PROGRAM_ID_SET(Array, Ed, It, Old, New)         \
719   for (It = 0; It < Ed->collection->programs.Array##_count; ++It) \
720     _edje_part_program_id_set(Ed->collection->programs.Array[It], Old, New);
721 
722    EDJE_EDIT_PROGRAM_ID_SET(fnmatch, ed, j, old_id, new_id);
723    EDJE_EDIT_PROGRAM_ID_SET(strcmp, ed, j, old_id, new_id);
724    EDJE_EDIT_PROGRAM_ID_SET(strncmp, ed, j, old_id, new_id);
725    EDJE_EDIT_PROGRAM_ID_SET(strrncmp, ed, j, old_id, new_id);
726    EDJE_EDIT_PROGRAM_ID_SET(nocmp, ed, j, old_id, new_id);
727 
728    /* Adjust table_parts */
729    if (new_id >= 0)
730      ed->table_parts[new_id] = rp;
731 }
732 
733 static void
_edje_part_description_id_switch(int type,Edje_Part_Description_Common * c,int id1,int id2)734 _edje_part_description_id_switch(int type, Edje_Part_Description_Common *c, int id1, int id2)
735 {
736    if (c->rel1.id_x == id1)
737      c->rel1.id_x = id2;
738    else if (c->rel1.id_x == id2)
739      c->rel1.id_x = id1;
740    if (c->rel1.id_y == id1)
741      c->rel1.id_y = id2;
742    else if (c->rel1.id_y == id2)
743      c->rel1.id_y = id1;
744    if (c->rel2.id_x == id1)
745      c->rel2.id_x = id2;
746    else if (c->rel2.id_x == id2)
747      c->rel2.id_x = id1;
748    if (c->rel2.id_y == id1)
749      c->rel2.id_y = id2;
750    else if (c->rel2.id_y == id2)
751      c->rel2.id_y = id1;
752    if (c->clip_to_id == id1)
753      c->clip_to_id = id2;
754    else if (c->clip_to_id == id2)
755      c->clip_to_id = id1;
756 
757    if (type == EDJE_PART_TYPE_TEXT
758        || type == EDJE_PART_TYPE_TEXTBLOCK)
759      {
760         Edje_Part_Description_Text *t;
761         t = (Edje_Part_Description_Text *)c;
762 
763         if (t->text.id_source == id1) t->text.id_source = id2;
764         else if (t->text.id_source == id2)
765           t->text.id_source = id1;
766         if (t->text.id_text_source == id1) t->text.id_text_source = id2;
767         else if (t->text.id_text_source == id2)
768           t->text.id_text_source = id1;
769      }
770 
771    if (c->map.id_persp == id1)
772      c->map.id_persp = id2;
773    else if (c->map.id_persp == id2)
774      c->map.id_persp = id1;
775 
776    if (c->map.id_light == id1)
777      c->map.id_light = id2;
778    else if (c->map.id_light == id2)
779      c->map.id_light = id1;
780 
781 
782    if (c->map.rot.id_center == id1)
783      c->map.rot.id_center = id2;
784    else if (c->map.rot.id_center == id2)
785      c->map.rot.id_center = id1;
786 }
787 
788 static void
_edje_part_program_id_switch(Edje_Program * epr,int id1,int id2)789 _edje_part_program_id_switch(Edje_Program *epr, int id1, int id2)
790 {
791    Edje_Program_Target *pt;
792    Eina_List *ll;
793 
794    if (epr->action != EDJE_ACTION_TYPE_STATE_SET)
795      return;
796 
797    EINA_LIST_FOREACH(epr->targets, ll, pt)
798      {
799         if (pt->id == id1) pt->id = id2;
800         else if (pt->id == id2)
801           pt->id = id1;
802      }
803 }
804 
805 static void
_edje_parts_id_switch(Edje * ed,Edje_Real_Part * rp1,Edje_Real_Part * rp2)806 _edje_parts_id_switch(Edje *ed, Edje_Real_Part *rp1, Edje_Real_Part *rp2)
807 {
808    /* This function switch the id of two parts.
809     * All the depedency will be updated too.
810     * Also the table_parts is updated,
811     * The parts list isn't touched
812     */
813    int id1;
814    int id2;
815    unsigned int i;
816 
817    //printf("SWITCH ID OF PART %d AND %d\n", rp1->part->id, rp2->part->id);
818 
819    if (!ed || !rp1 || !rp2) return;
820    if (rp1 == rp2) return;
821 
822    id1 = rp1->part->id;
823    id2 = rp2->part->id;
824 
825    /* Switch ids */
826    rp1->part->id = id2;
827    rp2->part->id = id1;
828 
829    /* adjust table_parts */
830    ed->table_parts[id1] = rp2;
831    ed->table_parts[id2] = rp1;
832 
833    // Fix all the dependecies in all parts...
834    for (i = 0; i < ed->collection->parts_count; ++i)
835      {
836         unsigned int j;
837         Edje_Part *p;
838 
839         p = ed->collection->parts[i];
840 
841         //printf("   search id: %d in %s\n", old_id, p->name);
842         if (p->clip_to_id == id1) p->clip_to_id = id2;
843         else if (p->clip_to_id == id2)
844           p->clip_to_id = id1;
845         if (p->dragable.confine_id == id1) p->dragable.confine_id = id2;
846         else if (p->dragable.confine_id == id2)
847           p->dragable.confine_id = id1;
848 
849         // ...in default description
850         _edje_part_description_id_switch(p->type, p->default_desc, id1, id2);
851 
852         // ...and in all other descriptions
853         for (j = 0; j < p->other.desc_count; ++j)
854           _edje_part_description_id_switch(p->type, p->other.desc[j], id1, id2);
855      }
856 
857    //...and also in programs targets
858 #define EDJE_EDIT_PROGRAM_SWITCH(Array, Ed, It, Id1, Id2)         \
859   for (It = 0; It < Ed->collection->programs.Array##_count; ++It) \
860     _edje_part_program_id_switch(Ed->collection->programs.Array[i], Id1, Id2);
861 
862    EDJE_EDIT_PROGRAM_SWITCH(fnmatch, ed, i, id1, id2);
863    EDJE_EDIT_PROGRAM_SWITCH(strcmp, ed, i, id1, id2);
864    EDJE_EDIT_PROGRAM_SWITCH(strncmp, ed, i, id1, id2);
865    EDJE_EDIT_PROGRAM_SWITCH(strrncmp, ed, i, id1, id2);
866    EDJE_EDIT_PROGRAM_SWITCH(nocmp, ed, i, id1, id2);
867    //TODO Real part dependencies are ok?
868 }
869 
870 static void
_edje_fix_parts_id(Edje * ed)871 _edje_fix_parts_id(Edje *ed)
872 {
873    /* We use this to clear the id hole leaved when a part is removed.
874     * After the execution of this function all parts will have a right
875     * (uniqe & ordered) id. The table_parts is also updated.
876     */
877    unsigned int i;
878    int correct_id;
879    unsigned short count;
880 
881    //printf("FIXING PARTS ID \n");
882 
883    //TODO order the list first to be more robust
884 
885    /* Give a correct id to all the parts */
886    correct_id = 0;
887    for (i = 0; i < ed->collection->parts_count; ++i)
888      {
889         Edje_Part *p;
890 
891         p = ed->collection->parts[i];
892 
893         //printf(" [%d]Checking part: %s id: %d\n", correct_id, p->name, p->id);
894         if (p->id != correct_id)
895           if (ed->table_parts[p->id])
896             _edje_part_id_set(ed, ed->table_parts[p->id], correct_id);
897 
898         correct_id++;
899      }
900 
901    /* If we have removed some parts realloc table_parts */
902    count = (unsigned short)ed->collection->parts_count;
903    if (count != ed->table_parts_size)
904      {
905         ed->table_parts = realloc(ed->table_parts, sizeof(Edje_Real_Part *) * count);
906         ed->table_parts_size = count;
907      }
908 
909    //printf("\n");
910 }
911 
912 static void
_edje_if_string_free(Edje * ed,const char ** str)913 _edje_if_string_free(Edje *ed, const char **str)
914 {
915    Eet_Dictionary *dict;
916 
917    if (!ed || !str) return;
918    if (!ed->file->allocated_strings) goto the_end;
919 
920    dict = eet_dictionary_get(ed->file->ef);
921 
922    if (!eet_dictionary_string_check(dict, *str))
923      eina_stringshare_del(*str);
924 
925  the_end:
926    *str = NULL;
927 }
928 
929 static void
_edje_if_string_replace(Edje * ed,const char ** str,const char * str_new)930 _edje_if_string_replace(Edje *ed, const char **str, const char *str_new)
931 {
932    Eet_Dictionary *dict;
933 
934    if (!ed || !str) return;
935 
936    ed->file->allocated_strings = EINA_TRUE;
937    dict = eet_dictionary_get(ed->file->ef);
938    if (*str && eet_dictionary_string_check(dict, *str))
939      *str = eina_stringshare_add(str_new);
940    else
941      eina_stringshare_replace(str, str_new);
942 }
943 
944 static Edje_Style *
_edje_edit_style_get(Edje * ed,const char * name)945 _edje_edit_style_get(Edje *ed, const char *name)
946 {
947    Eina_List *l;
948    Edje_Style *s;
949 
950    if (!ed || !ed->file || !ed->file->styles || !name)
951      return NULL;
952 
953    EINA_LIST_FOREACH(ed->file->styles, l, s)
954      if (s->name && !strcmp(s->name, name))
955        return s;
956 
957    return NULL;
958 }
959 
960 static Edje_Style_Tag *
_edje_edit_style_tag_get(Edje * ed,const char * style,const char * name)961 _edje_edit_style_tag_get(Edje *ed, const char *style, const char *name)
962 {
963    Eina_List *l;
964    Edje_Style *s;
965    Edje_Style_Tag *t;
966 
967    if (!ed || !ed->file || !ed->file->styles || !name)
968      return NULL;
969 
970    s = _edje_edit_style_get(ed, style);
971 
972    EINA_LIST_FOREACH(s->tags, l, t)
973      if (t->key && !strcmp(t->key, name))
974        return t;
975 
976    return NULL;
977 }
978 
979 static Edje_External_Directory_Entry *
_edje_edit_external_get(Edje * ed,const char * name)980 _edje_edit_external_get(Edje *ed, const char *name)
981 {
982    unsigned int i;
983 
984    if (!ed || !ed->file || !ed->file->external_dir || !name)
985      return NULL;
986 
987    for (i = 0; i < ed->file->external_dir->entries_count; ++i)
988      if (ed->file->external_dir->entries[i].entry
989          && !strcmp(ed->file->external_dir->entries[i].entry, name))
990        return ed->file->external_dir->entries + i;
991 
992    return NULL;
993 }
994 
995 static void
_edje_edit_group_references_update(Evas_Object * obj,const char * old_group_name,const char * new_group_name)996 _edje_edit_group_references_update(Evas_Object *obj, const char *old_group_name, const char *new_group_name)
997 {
998    Eina_Iterator *i;
999    Eina_List *pll, *pl;
1000 //   Edje_Part_Collection *pc;
1001    Edje_Part_Collection_Directory_Entry *pce;
1002    char *part_name;
1003    const char *source, *old;
1004    Edje_Part_Type type;
1005    Evas_Object *part_obj;
1006 
1007    GET_ED_OR_RETURN();
1008 
1009 //   pc = ed->collection;
1010 
1011    part_obj = edje_edit_object_add(ed->base.evas);
1012 
1013    old = eina_stringshare_add(old_group_name);
1014 
1015    i = eina_hash_iterator_data_new(ed->file->collection);
1016 
1017    EINA_ITERATOR_FOREACH(i, pce)
1018      {
1019         edje_object_file_set(part_obj, ed->file->path, pce->entry);
1020 
1021         pl = edje_edit_parts_list_get(part_obj);
1022 
1023         EINA_LIST_FOREACH(pl, pll, part_name)
1024           {
1025              source = edje_edit_part_source_get(part_obj, part_name);
1026              type = edje_edit_part_type_get(part_obj, part_name);
1027 
1028              if (type == EDJE_PART_TYPE_GROUP && source == old)
1029                edje_edit_part_source_set(part_obj, part_name, new_group_name);
1030 
1031              if (source)
1032                eina_stringshare_del(source);
1033           }
1034      }
1035 
1036    eina_iterator_free(i);
1037 
1038    eina_stringshare_del(old);
1039 
1040    evas_object_del(part_obj);
1041 }
1042 
1043 static void
_edje_edit_flag_script_dirty(Edje_Edit * eed,Eina_Bool all)1044 _edje_edit_flag_script_dirty(Edje_Edit *eed, Eina_Bool all)
1045 {
1046    eed->script_need_recompile = EINA_TRUE;
1047    if (all)
1048      eed->all_dirty = EINA_TRUE;
1049 }
1050 
1051 /*****************/
1052 /*  GENERAL API  */
1053 /*****************/
1054 
1055 EAPI void
edje_edit_string_list_free(Eina_List * lst)1056 edje_edit_string_list_free(Eina_List *lst)
1057 {
1058    //printf("FREE LIST: \n");
1059    while (lst)
1060      {
1061         if (eina_list_data_get(lst)) eina_stringshare_del(eina_list_data_get(lst));
1062         //printf("FREE: %s\n", eina_list_data_get(lst));
1063         lst = eina_list_remove(lst, eina_list_data_get(lst));
1064      }
1065 }
1066 
1067 EAPI void
edje_edit_string_free(const char * str)1068 edje_edit_string_free(const char *str)
1069 {
1070    if (str) eina_stringshare_del(str);
1071 }
1072 
1073 EAPI const char *
edje_edit_compiler_get(Evas_Object * obj)1074 edje_edit_compiler_get(Evas_Object *obj)
1075 {
1076    GET_ED_OR_RETURN(0);
1077    return eina_stringshare_add(ed->file->compiler);
1078 }
1079 
1080 /****************/
1081 /*  SOUNDS API  */
1082 /****************/
1083 
1084 EAPI Eina_List *
edje_edit_sound_samples_list_get(Evas_Object * obj)1085 edje_edit_sound_samples_list_get(Evas_Object *obj)
1086 {
1087    Eina_List *sounds_samples = NULL;
1088    unsigned int i;
1089 
1090    GET_ED_OR_RETURN(NULL);
1091 
1092    if ((!ed->file) || (!ed->file->sound_dir))
1093      return NULL;
1094 
1095    for (i = 0; i < ed->file->sound_dir->samples_count; ++i)
1096      sounds_samples = eina_list_append(sounds_samples,
1097                                        eina_stringshare_add(ed->file->sound_dir->samples[i].name));
1098 
1099    return sounds_samples;
1100 }
1101 
1102 EAPI Eina_List *
edje_edit_sound_tones_list_get(Evas_Object * obj)1103 edje_edit_sound_tones_list_get(Evas_Object *obj)
1104 {
1105    Eina_List *sounds_tones = NULL;
1106    unsigned int i;
1107 
1108    GET_ED_OR_RETURN(NULL);
1109 
1110    if ((!ed->file) || (!ed->file->sound_dir))
1111      return NULL;
1112 
1113    for (i = 0; i < ed->file->sound_dir->tones_count; ++i)
1114      sounds_tones = eina_list_append(sounds_tones,
1115                                      eina_stringshare_add(ed->file->sound_dir->tones[i].name));
1116 
1117    return sounds_tones;
1118 }
1119 
1120 static Eina_Bool _edje_edit_collection_save(Eet_File *eetf, Edje_Part_Collection *epc);
1121 
1122 static Eina_Bool
_delete_play_actions(Evas_Object * obj,const char * name,int action_type,Eet_File * eetf)1123 _delete_play_actions(Evas_Object *obj, const char *name, int action_type, Eet_File *eetf)
1124 {
1125    GET_ED_OR_RETURN(EINA_FALSE);
1126    Eina_Iterator *it = eina_hash_iterator_data_new(ed->file->collection);
1127    Edje_Part_Collection_Directory_Entry *pce;
1128 
1129    EINA_ITERATOR_FOREACH(it, pce)
1130      {
1131         Eina_Bool is_collection_changed = EINA_FALSE;
1132         Evas_Object *eeo;
1133         Eina_List *programs_list;
1134         Edje *eed;
1135         int i;
1136 
1137         if (pce->group_alias)
1138           continue;
1139 
1140         eeo = edje_edit_object_add(ed->base.evas);
1141         if (!efl_isa(eeo, EFL_CANVAS_LAYOUT_CLASS))
1142           return EINA_FALSE;
1143 
1144         if (!edje_object_file_set(eeo, ed->file->path, pce->entry))
1145           {
1146              evas_object_del(eeo);
1147              continue;
1148           }
1149 
1150         programs_list = edje_edit_programs_list_get(eeo);
1151         if (!programs_list)
1152           {
1153              evas_object_del(eeo);
1154              continue;
1155           }
1156 
1157         eed = efl_data_scope_get(eeo, EFL_CANVAS_LAYOUT_CLASS);
1158         for (i = 0; i < eed->collection->patterns.table_programs_size; i++)
1159           {
1160              Edje_Program *program;
1161 
1162              program = eed->collection->patterns.table_programs[i];
1163              if (program->action != action_type)
1164                continue;
1165 
1166              if ((action_type == EDJE_ACTION_TYPE_SOUND_SAMPLE) &&
1167                  !strcmp(program->sample_name, name))
1168                {
1169                   program->speed = 0;
1170                   program->channel = EDJE_CHANNEL_EFFECT;
1171                   _edje_if_string_free(eed, &program->sample_name);
1172                   program->action = EDJE_ACTION_TYPE_NONE;
1173                   is_collection_changed = EINA_TRUE;
1174                }
1175              else if ((action_type == EDJE_ACTION_TYPE_SOUND_TONE) &&
1176                       !strcmp(program->tone_name, name))
1177                {
1178                   program->duration = 0;
1179                   _edje_if_string_free(eed, &program->tone_name);
1180                   program->action = EDJE_ACTION_TYPE_NONE;
1181                   is_collection_changed = EINA_TRUE;
1182                }
1183           }
1184         if (is_collection_changed)
1185           _edje_edit_collection_save(eetf, eed->collection);
1186         evas_object_del(eeo);
1187      }
1188 
1189    eina_iterator_free(it);
1190    return EINA_TRUE;
1191 }
1192 
1193 static void
_initialize_sound_dir(Edje * ed)1194 _initialize_sound_dir(Edje *ed)
1195 {
1196    if (ed->file->sound_dir)
1197      return;
1198    ed->file->sound_dir = _alloc(sizeof(Edje_Sound_Directory));
1199    ed->file->sound_dir->samples = NULL;
1200    ed->file->sound_dir->tones = NULL;
1201    ed->file->sound_dir->samples_count = 0;
1202    ed->file->sound_dir->tones_count = 0;
1203 }
1204 
1205 #define GET_TONE_BY_NAME(_tone_p, _name)                         \
1206   {                                                              \
1207      unsigned int i = 0;                                         \
1208      for (i = 0; i < ed->file->sound_dir->tones_count; ++i)      \
1209        {                                                         \
1210           _tone_p = ed->file->sound_dir->tones + i;              \
1211           if (!strcmp(_name, _tone_p->name))                     \
1212             break;                                               \
1213        }                                                         \
1214      if (i == ed->file->sound_dir->tones_count) _tone_p = NULL;  \
1215   }
1216 
1217 EAPI Eina_Bool
edje_edit_sound_sample_add(Evas_Object * obj,const char * name,const char * snd_src)1218 edje_edit_sound_sample_add(Evas_Object *obj, const char *name, const char *snd_src)
1219 {
1220    if (!name) return EINA_FALSE;
1221    if (!snd_src) return EINA_FALSE;
1222 
1223    GET_ED_OR_RETURN(EINA_FALSE);
1224 
1225    Edje_Sound_Sample *sound_sample = NULL;
1226    unsigned int i = 0;
1227    char sample[PATH_MAX];
1228    int id = 0;
1229 
1230    _initialize_sound_dir(ed);
1231 
1232    for (i = 0; i < ed->file->sound_dir->samples_count; ++i)
1233      {
1234         sound_sample = ed->file->sound_dir->samples + i;
1235         if (!strcmp(name, sound_sample->name))
1236           {
1237              WRN("Can not add new sound sample because"
1238                  "sample named \"%s\" already exists.", name);
1239              return EINA_FALSE;
1240           }
1241      }
1242 
1243    if (ed->file->sound_dir->samples)
1244      {
1245         sound_sample = ed->file->sound_dir->samples +
1246           ed->file->sound_dir->samples_count - 1;
1247         id = sound_sample->id + 1;
1248         snprintf(sample, sizeof(sample), "edje/sounds/%i", id);
1249      }
1250    else
1251      strcpy(sample, "edje/sounds/0");
1252 
1253    if (!_edje_edit_file_import(ed, snd_src, sample, 0))
1254      return EINA_FALSE;
1255 
1256    if (sound_sample)
1257      sound_sample++;
1258    ++ed->file->sound_dir->samples_count;
1259 
1260    ed->file->sound_dir->samples = realloc(ed->file->sound_dir->samples,
1261                                           sizeof(Edje_Sound_Sample) *
1262                                           ed->file->sound_dir->samples_count);
1263 
1264    sound_sample = ed->file->sound_dir->samples +
1265      ed->file->sound_dir->samples_count - 1;
1266    sound_sample->name = (char *)eina_stringshare_add(name);
1267    sound_sample->snd_src = (char *)eina_stringshare_add(ecore_file_file_get(snd_src));
1268    sound_sample->compression = EDJE_SOUND_SOURCE_TYPE_INLINE_RAW;
1269    sound_sample->id = id;
1270    sound_sample->mode = 0;
1271    sound_sample->quality = 0;
1272 
1273    return EINA_TRUE;
1274 }
1275 
1276 EAPI Eina_Bool
edje_edit_sound_sample_del(Evas_Object * obj,const char * name)1277 edje_edit_sound_sample_del(Evas_Object *obj, const char *name)
1278 {
1279    Edje_Sound_Sample *sound_sample = NULL;
1280    unsigned int i = 0;
1281 
1282    GET_ED_OR_RETURN(EINA_FALSE);
1283 
1284    if (!name) return EINA_FALSE;
1285    if (!ed->file) return EINA_FALSE;
1286    if (!ed->path) return EINA_FALSE;
1287 
1288    if ((!ed->file->sound_dir) || (!ed->file->sound_dir->samples))
1289      {
1290         WRN("Unable to delete sample \"%s\". The samples list is empty.", name);
1291         return EINA_FALSE;
1292      }
1293 
1294    for (i = 0; i < ed->file->sound_dir->samples_count; ++i)
1295      {
1296         sound_sample = ed->file->sound_dir->samples + i;
1297         if (!strcmp(name, sound_sample->name))
1298           break;
1299      }
1300    if (i == ed->file->sound_dir->samples_count)
1301      {
1302         WRN("Unable to delete sample \"%s\". It does not exist.", name);
1303         return EINA_FALSE;
1304      }
1305 
1306    {
1307       char sample[PATH_MAX];
1308       Eet_File *eetf;
1309       Edje_Sound_Sample *sound_sample_last;
1310 
1311       eetf = _edje_edit_eet_open(ed, EET_FILE_MODE_READ_WRITE);
1312       if (!eetf)
1313         return EINA_FALSE;
1314 
1315       snprintf(sample, sizeof(sample), "edje/sounds/%i", sound_sample->id);
1316 
1317       if (eet_delete(eetf, sample) <= 0)
1318         {
1319            WRN("Unable to delete \"%s\" sound", sample);
1320            _edje_edit_eet_close(eetf);
1321            return EINA_FALSE;
1322         }
1323 
1324       _edje_if_string_free(ed, &sound_sample->name);
1325       --ed->file->sound_dir->samples_count;
1326 
1327       sound_sample_last = ed->file->sound_dir->samples +
1328         ed->file->sound_dir->samples_count - 1;
1329 
1330       while (sound_sample <= sound_sample_last)
1331         {
1332            *sound_sample = *(sound_sample + 1);
1333            sound_sample++;
1334         }
1335 
1336       ed->file->sound_dir->samples = realloc(ed->file->sound_dir->samples,
1337                                              sizeof(Edje_Sound_Sample) *
1338                                              ed->file->sound_dir->samples_count);
1339 
1340       if (!_delete_play_actions(obj, name, EDJE_ACTION_TYPE_SOUND_SAMPLE, eetf))
1341         {
1342            _edje_edit_eet_close(eetf);
1343            return EINA_FALSE;
1344         }
1345 
1346       if (!_edje_edit_edje_file_save(eetf, ed->file))
1347         {
1348            _edje_edit_eet_close(eetf);
1349            return EINA_FALSE;
1350         }
1351       _edje_edit_eet_close(eetf);
1352    }
1353 
1354    GET_EED_OR_RETURN(EINA_FALSE);
1355    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
1356 
1357    return EINA_TRUE;
1358 }
1359 
1360 EAPI Eina_Bool
edje_edit_sound_tone_add(Evas_Object * obj,const char * name,int frequency)1361 edje_edit_sound_tone_add(Evas_Object *obj, const char *name, int frequency)
1362 {
1363    if (!name) return EINA_FALSE;
1364    if ((frequency < 20) || (frequency > 20000))
1365      return EINA_FALSE;
1366 
1367    GET_ED_OR_RETURN(EINA_FALSE);
1368 
1369    Edje_Sound_Tone *sound_tone = NULL;
1370    Edje_Sound_Tone *sound_tones_array = NULL;
1371    unsigned int i = 0;
1372    int id = 0;
1373 
1374    _initialize_sound_dir(ed);
1375 
1376    for (i = 0; i < ed->file->sound_dir->tones_count; ++i)
1377      {
1378         sound_tone = ed->file->sound_dir->tones + i;
1379         if (!strcmp(name, sound_tone->name))
1380           {
1381              WRN("Can not add new tone because"
1382                  "tone named \"%s\" already exists.", name);
1383              return EINA_FALSE;
1384           }
1385      }
1386    ed->file->sound_dir->tones_count++;
1387 
1388    sound_tones_array = realloc(ed->file->sound_dir->tones,
1389                                sizeof(Edje_Sound_Tone) *
1390                                ed->file->sound_dir->tones_count);
1391    if (sound_tones_array)
1392      ed->file->sound_dir->tones = sound_tones_array;
1393    else return EINA_FALSE;
1394 
1395    sound_tone = ed->file->sound_dir->tones +
1396      ed->file->sound_dir->tones_count - 1;
1397    sound_tone->name = (char *)eina_stringshare_add(name);
1398    sound_tone->value = frequency;
1399    sound_tone->id = id;
1400 
1401    return EINA_TRUE;
1402 }
1403 
1404 EAPI Eina_Bool
edje_edit_sound_tone_del(Evas_Object * obj,const char * name)1405 edje_edit_sound_tone_del(Evas_Object *obj, const char *name)
1406 {
1407    GET_ED_OR_RETURN(EINA_FALSE);
1408 
1409    if (!name) return EINA_FALSE;
1410    if (!ed->file) return EINA_FALSE;
1411    if (!ed->path) return EINA_FALSE;
1412 
1413    if ((!ed->file->sound_dir) || (!ed->file->sound_dir->tones))
1414      {
1415         WRN("Unable to delete tone \"%s\". The tones list is empty.", name);
1416         return EINA_FALSE;
1417      }
1418 
1419    Edje_Sound_Tone *sound_tone;
1420    GET_TONE_BY_NAME(sound_tone, name);
1421    if (!sound_tone)
1422      {
1423         WRN("Unable to delete tone \"%s\". It does not exist.", name);
1424         return EINA_FALSE;
1425      }
1426 
1427    {
1428       Eet_File *eetf;
1429 
1430       eetf = _edje_edit_eet_open(ed, EET_FILE_MODE_READ_WRITE);
1431       if (!eetf)
1432         return EINA_FALSE;
1433 
1434       _edje_if_string_free(ed, &sound_tone->name);
1435       --ed->file->sound_dir->tones_count;
1436 
1437       Edje_Sound_Tone *sound_tone_last = ed->file->sound_dir->tones +
1438         ed->file->sound_dir->tones_count - 1;
1439 
1440       while (sound_tone <= sound_tone_last)
1441         {
1442            *sound_tone = *(sound_tone + 1);
1443            sound_tone++;
1444         }
1445 
1446       ed->file->sound_dir->tones = realloc(ed->file->sound_dir->tones,
1447                                            sizeof(Edje_Sound_Tone) *
1448                                            ed->file->sound_dir->tones_count);
1449 
1450       if (!_delete_play_actions(obj, name, EDJE_ACTION_TYPE_SOUND_TONE, eetf))
1451         {
1452            _edje_edit_eet_close(eetf);
1453            return EINA_FALSE;
1454         }
1455 
1456       if (!_edje_edit_edje_file_save(eetf, ed->file))
1457         {
1458            _edje_edit_eet_close(eetf);
1459            return EINA_FALSE;
1460         }
1461       _edje_edit_eet_close(eetf);
1462    }
1463 
1464    GET_EED_OR_RETURN(EINA_FALSE);
1465    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
1466 
1467    return EINA_TRUE;
1468 }
1469 
1470 EAPI Eina_Bool
edje_edit_sound_tone_frequency_set(Evas_Object * obj,const char * name,int frequency)1471 edje_edit_sound_tone_frequency_set(Evas_Object *obj, const char *name, int frequency)
1472 {
1473    Edje_Sound_Tone *tone;
1474    if ((frequency < 20) || (frequency > 20000)) return EINA_FALSE;
1475    GET_ED_OR_RETURN(EINA_FALSE);
1476    GET_TONE_BY_NAME(tone, name);
1477    if (tone)
1478      {
1479         tone->value = frequency;
1480         return EINA_TRUE;
1481      }
1482    return EINA_FALSE;
1483 }
1484 
1485 EAPI int
edje_edit_sound_tone_frequency_get(Evas_Object * obj,const char * name)1486 edje_edit_sound_tone_frequency_get(Evas_Object *obj, const char *name)
1487 {
1488    Edje_Sound_Tone *tone;
1489    GET_ED_OR_RETURN(-1);
1490    GET_TONE_BY_NAME(tone, name);
1491    if (tone)
1492      return tone->value;
1493    return -1;
1494 }
1495 
1496 EAPI double
edje_edit_sound_compression_rate_get(Evas_Object * obj,const char * sound)1497 edje_edit_sound_compression_rate_get(Evas_Object *obj, const char *sound)
1498 {
1499    Edje_Sound_Sample *ss = NULL;
1500    unsigned int i;
1501 
1502    GET_ED_OR_RETURN(-1);
1503 
1504    if ((!ed->file) || (!ed->file->sound_dir))
1505      return -1;
1506 
1507    for (i = 0; i < ed->file->sound_dir->samples_count; i++)
1508      {
1509         ss = ed->file->sound_dir->samples + i;
1510         if ((ss->name) && (!strcmp(sound, ss->name)))
1511           break;
1512      }
1513 
1514    if (i == ed->file->sound_dir->samples_count)
1515      return -1;
1516 
1517    return ss->quality;
1518 }
1519 
1520 EAPI Eina_Bool
edje_edit_sound_compression_rate_set(Evas_Object * obj,const char * sound,double rate)1521 edje_edit_sound_compression_rate_set(Evas_Object *obj, const char *sound, double rate)
1522 {
1523    Edje_Sound_Sample *ss = NULL;
1524    unsigned int i;
1525 
1526    GET_ED_OR_RETURN(EINA_FALSE);
1527 
1528    if ((!ed->file) || (!ed->file->sound_dir))
1529      return EINA_FALSE;
1530 
1531    for (i = 0; i < ed->file->sound_dir->samples_count; i++)
1532      {
1533         ss = ed->file->sound_dir->samples + i;
1534         if ((ss->name) && (!strcmp(sound, ss->name)))
1535           break;
1536      }
1537 
1538    if (i == ed->file->sound_dir->samples_count)
1539      return EINA_FALSE;
1540 
1541    ss->quality = rate;
1542    return EINA_TRUE;
1543 }
1544 
1545 #undef GET_TONE_BY_NAME
1546 
1547 EAPI Edje_Edit_Sound_Comp
edje_edit_sound_compression_type_get(Evas_Object * obj,const char * sound)1548 edje_edit_sound_compression_type_get(Evas_Object *obj, const char *sound)
1549 {
1550    Edje_Sound_Sample *ss = NULL;
1551    unsigned int i;
1552 
1553    GET_ED_OR_RETURN(-1);
1554 
1555    if ((!ed->file) || (!ed->file->sound_dir))
1556      return -1;
1557 
1558    for (i = 0; i < ed->file->sound_dir->samples_count; i++)
1559      {
1560         ss = ed->file->sound_dir->samples + i;
1561         if ((ss->name) && (!strcmp(sound, ss->name)))
1562           break;
1563      }
1564 
1565    if (i == ed->file->sound_dir->samples_count)
1566      return -1;
1567 
1568    return (Edje_Edit_Sound_Comp)ss->compression;
1569 }
1570 
1571 EAPI Eina_Bool
edje_edit_sound_compression_type_set(Evas_Object * obj,const char * sound,Edje_Edit_Sound_Comp sc)1572 edje_edit_sound_compression_type_set(Evas_Object *obj, const char *sound, Edje_Edit_Sound_Comp sc)
1573 {
1574    Edje_Sound_Sample *ss = NULL;
1575    unsigned int i;
1576 
1577    if ((sc <= EDJE_EDIT_SOUND_COMP_NONE) ||
1578        (sc > EDJE_EDIT_SOUND_COMP_AS_IS))
1579      return EINA_FALSE;
1580    GET_ED_OR_RETURN(EINA_FALSE);
1581 
1582    if ((!ed->file) || (!ed->file->sound_dir))
1583      return EINA_FALSE;
1584 
1585    for (i = 0; i < ed->file->sound_dir->samples_count; i++)
1586      {
1587         ss = ed->file->sound_dir->samples + i;
1588         if ((ss->name) && (!strcmp(sound, ss->name)))
1589           break;
1590      }
1591 
1592    if (i == ed->file->sound_dir->samples_count)
1593      return EINA_FALSE;
1594 
1595    ss->compression = (int)sc;
1596    return EINA_TRUE;
1597 }
1598 
1599 EAPI Eina_Binbuf *
edje_edit_sound_samplebuffer_get(Evas_Object * obj,const char * sample_name)1600 edje_edit_sound_samplebuffer_get(Evas_Object *obj, const char *sample_name)
1601 {
1602    Eet_File *ef;
1603    Edje_Sound_Sample *sample;
1604    char snd_id_str[PATH_MAX];
1605    int i, len;
1606    const void *data;
1607 
1608    if (!sample_name)
1609      {
1610         ERR("Given Sample Name is NULL\n");
1611         return NULL;
1612      }
1613 
1614    GET_ED_OR_RETURN(NULL);
1615 
1616    if ((!ed) || (!ed->file) || (!ed->file->sound_dir))
1617      return NULL;
1618 
1619    for (i = 0; i < (int)ed->file->sound_dir->samples_count; i++)
1620      {
1621         sample = &ed->file->sound_dir->samples[i];
1622         if (!strcmp(sample->name, sample_name))
1623           {
1624              ef = _edje_edit_eet_open(ed, EET_FILE_MODE_READ);
1625              if (!ef)
1626                return NULL;
1627              snprintf(snd_id_str, sizeof(snd_id_str), "edje/sounds/%i", sample->id);
1628              data = eet_read(ef, snd_id_str, &len);
1629              if (len <= 0)
1630                {
1631                   ERR("Sample from edj file '%s' has 0 length", ed->path);
1632                   _edje_edit_eet_close(ef);
1633                   return NULL;
1634                }
1635              _edje_edit_eet_close(ef);
1636              return eina_binbuf_manage_new(data, len, EINA_TRUE);
1637           }
1638      }
1639    return NULL;
1640 }
1641 
1642 EAPI const char *
edje_edit_sound_samplesource_get(Evas_Object * obj,const char * sample_name)1643 edje_edit_sound_samplesource_get(Evas_Object *obj, const char *sample_name)
1644 {
1645    Edje_Sound_Sample *sample;
1646    int i;
1647 
1648    if (!sample_name)
1649      {
1650         ERR("Given Sample Name is NULL");
1651         return NULL;
1652      }
1653 
1654    GET_ED_OR_RETURN(NULL);
1655 
1656    if ((!ed) || (!ed->file) || (!ed->file->sound_dir))
1657      return NULL;
1658 
1659    for (i = 0; i < (int)ed->file->sound_dir->samples_count; i++)
1660      {
1661         sample = &ed->file->sound_dir->samples[i];
1662         if (!strcmp(sample->name, sample_name))
1663           return eina_stringshare_add(sample->snd_src);
1664      }
1665 
1666    return NULL;
1667 }
1668 
1669 /****************/
1670 /*  GROUPS API  */
1671 /****************/
1672 
1673 static void
_mempools_add(Edje_Part_Collection_Directory_Entry * de)1674 _mempools_add(Edje_Part_Collection_Directory_Entry *de)
1675 {
1676    de->mp = calloc(1, sizeof(Edje_Part_Collection_Directory_Entry_Mp));
1677    if (!de->mp)
1678      return;
1679 #define EDIT_EMN(Tp, Sz, Ce) \
1680   Ce->mp->mp.Tp = eina_mempool_add("chained_mempool", #Tp, NULL, sizeof (Sz), 8);
1681 #define EDIT_EMNP(Tp, Sz, Ce) \
1682   Ce->mp->mp_rtl.Tp = eina_mempool_add("chained_mempool", #Tp, NULL, sizeof (Sz), 8);
1683 
1684    EDIT_EMN(RECTANGLE, Edje_Part_Description_Common, de);
1685    EDIT_EMN(TEXT, Edje_Part_Description_Text, de);
1686    EDIT_EMN(IMAGE, Edje_Part_Description_Image, de);
1687    EDIT_EMN(PROXY, Edje_Part_Description_Proxy, de);
1688    EDIT_EMN(SWALLOW, Edje_Part_Description_Common, de);
1689    EDIT_EMN(TEXTBLOCK, Edje_Part_Description_Text, de);
1690    EDIT_EMN(GROUP, Edje_Part_Description_Common, de);
1691    EDIT_EMN(BOX, Edje_Part_Description_Box, de);
1692    EDIT_EMN(TABLE, Edje_Part_Description_Table, de);
1693    EDIT_EMN(EXTERNAL, Edje_Part_Description_External, de);
1694    EDIT_EMN(SPACER, Edje_Part_Description_Common, de);
1695    EDIT_EMN(SNAPSHOT, Edje_Part_Description_Snapshot, de);
1696    EDIT_EMN(part, Edje_Part, de);
1697 
1698    EDIT_EMNP(RECTANGLE, Edje_Part_Description_Common, de);
1699    EDIT_EMNP(TEXT, Edje_Part_Description_Text, de);
1700    EDIT_EMNP(IMAGE, Edje_Part_Description_Image, de);
1701    EDIT_EMNP(PROXY, Edje_Part_Description_Proxy, de);
1702    EDIT_EMNP(SWALLOW, Edje_Part_Description_Common, de);
1703    EDIT_EMNP(TEXTBLOCK, Edje_Part_Description_Text, de);
1704    EDIT_EMNP(GROUP, Edje_Part_Description_Common, de);
1705    EDIT_EMNP(BOX, Edje_Part_Description_Box, de);
1706    EDIT_EMNP(TABLE, Edje_Part_Description_Table, de);
1707    EDIT_EMNP(EXTERNAL, Edje_Part_Description_External, de);
1708    EDIT_EMNP(SPACER, Edje_Part_Description_Common, de);
1709    EDIT_EMNP(SNAPSHOT, Edje_Part_Description_Snapshot, de);
1710 }
1711 
1712 EAPI Eina_Bool
edje_edit_group_copy(Evas_Object * obj,const char * group_name,const char * copy_name)1713 edje_edit_group_copy(Evas_Object *obj, const char *group_name, const char *copy_name)
1714 {
1715    Edje_Part_Collection_Directory_Entry *e;
1716    Edje_Part_Collection_Directory_Entry *de;
1717    Edje_Part_Collection_Directory_Entry *d;
1718    Edje_Part_Collection *epc;
1719    int id;
1720    int search;
1721    Eet_File *eetf;
1722    char buf[64];
1723    int count, script_count;
1724    void *data;
1725    char **keys, **c;
1726    Eina_Bool save_status = EINA_FALSE;
1727 
1728    GET_ED_OR_RETURN(EINA_FALSE);
1729    if (!ed->file || !ed->file->collection)
1730      return EINA_FALSE;
1731 
1732    e = eina_hash_find(ed->file->collection, group_name);
1733    if (!e) return EINA_FALSE;
1734    if (eina_hash_find(ed->file->collection, copy_name))
1735      return EINA_FALSE;
1736 
1737    eetf = _edje_edit_eet_open(ed, EET_FILE_MODE_READ_WRITE);
1738    if (!eetf)
1739      return EINA_FALSE;
1740 
1741    snprintf(buf, sizeof(buf), "edje/collections/%d", e->id);
1742    epc = eet_data_read(eetf, _edje_edd_edje_part_collection, buf);
1743    if (!epc)
1744      {
1745         _edje_edit_eet_close(eetf);
1746         return EINA_FALSE;
1747      }
1748 
1749    /* Search first free id */
1750    id = -1;
1751    search = 0;
1752    while (id == -1)
1753      {
1754         Eina_Iterator *i;
1755         Eina_Bool found = 0;
1756 
1757         i = eina_hash_iterator_data_new(ed->file->collection);
1758 
1759         EINA_ITERATOR_FOREACH(i, d)
1760           {
1761              if (search == d->id)
1762                {
1763                   found = 1;
1764                   break;
1765                }
1766           }
1767 
1768         eina_iterator_free(i);
1769 
1770         if (!found) id = search;
1771         else search++;
1772      }
1773 
1774    /* Create structs */
1775    de = _alloc(sizeof(Edje_Part_Collection_Directory_Entry));
1776    if (!de)
1777      {
1778         _edje_edit_eet_close(eetf);
1779         return EINA_FALSE;
1780      }
1781 
1782    /* Init Edje_Part_Collection_Directory_Entry */
1783    de->id = id;
1784    de->entry = eina_stringshare_add(copy_name);
1785    memcpy(&de->count, &e->count, sizeof (de->count));
1786 
1787    eina_hash_direct_add(ed->file->collection, de->entry, de);
1788 
1789    _mempools_add(de);
1790 
1791    epc->id = id;
1792    epc->part = eina_stringshare_add(copy_name);
1793    snprintf(buf, sizeof(buf), "edje/collections/%i", epc->id);
1794    eet_data_write(eetf, _edje_edd_edje_part_collection, buf, epc, 1);
1795 
1796    /* Copying Scripts */
1797    snprintf(buf, sizeof(buf), "edje/scripts/embryo/compiled/%d", e->id);
1798    data = eet_read(eetf, buf, &count);
1799    snprintf(buf, sizeof(buf), "edje/scripts/embryo/compiled/%d", epc->id);
1800    eet_write(eetf, buf, data, count, 1);
1801 
1802    snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%d", e->id);
1803    data = eet_read(eetf, buf, &count);
1804    snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%d", epc->id);
1805    eet_write(eetf, buf, data, count, 0);
1806 
1807    snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%d/*", e->id);
1808    keys = eet_list(eetf, buf, &count);
1809    if (keys)
1810      {
1811         while (count)
1812           {
1813              count--;
1814              data = eet_read(eetf, keys[count], &script_count);
1815              /* we need to save id of every script we are going to copy. */
1816              c = eina_str_split(keys[count], "/", 6);
1817              snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%d/%s", epc->id, c[5]);
1818              eet_write(eetf, buf, data, script_count, 0);
1819              free(c[0]);
1820              free(c);
1821           }
1822         free(keys);
1823      }
1824 
1825    save_status = _edje_edit_edje_file_save(eetf, ed->file);
1826 
1827    _edje_collection_free(ed->file, epc, de);
1828    _edje_edit_eet_close(eetf);
1829 
1830    return save_status;
1831 }
1832 
1833 EAPI Eina_Bool
edje_edit_group_add(Evas_Object * obj,const char * name)1834 edje_edit_group_add(Evas_Object *obj, const char *name)
1835 {
1836    Edje_Part_Collection_Directory_Entry *de;
1837    Edje_Part_Collection_Directory_Entry *d;
1838    Edje_Part_Collection *pc;
1839    int id;
1840    int search;
1841    //Code *cd;
1842 
1843    GET_ED_OR_RETURN(EINA_FALSE);
1844 
1845    //printf("ADD GROUP: %s \n", name);
1846 
1847    /* check if a group with the same name already exists */
1848    if (eina_hash_find(ed->file->collection, name))
1849      return EINA_FALSE;
1850 
1851    /* Create structs */
1852    de = _alloc(sizeof(Edje_Part_Collection_Directory_Entry));
1853    if (!de) return EINA_FALSE;
1854 
1855    pc = _alloc(sizeof(Edje_Part_Collection));
1856    if (!pc)
1857      {
1858         free(de);
1859         return EINA_FALSE;
1860      }
1861 
1862    /* Search first free id */
1863    id = -1;
1864    search = 0;
1865    while (id == -1)
1866      {
1867         Eina_Iterator *i;
1868         Eina_Bool found = 0;
1869 
1870         i = eina_hash_iterator_data_new(ed->file->collection);
1871 
1872         EINA_ITERATOR_FOREACH(i, d)
1873           {
1874              // printf("search if %d is free [id %d]\n", search, d->id);
1875              if (search == d->id)
1876                {
1877                   found = 1;
1878                   break;
1879                }
1880           }
1881 
1882         eina_iterator_free(i);
1883 
1884         if (!found) id = search;
1885         else search++;
1886      }
1887 
1888    /* Init Edje_Part_Collection_Directory_Entry */
1889    //printf(" new id: %d\n", id);
1890    de->id = id;
1891    de->entry = eina_stringshare_add(name);
1892    eina_hash_direct_add(ed->file->collection, de->entry, de);
1893 
1894    /* Init Edje_Part_Collection */
1895    pc->id = id;
1896    pc->references = 0;
1897    memset(&pc->programs, 0, sizeof (pc->programs));
1898    pc->parts = NULL;
1899    pc->data = NULL;
1900    pc->script = NULL;
1901    pc->part = eina_stringshare_add(name);
1902 
1903    //cd = _alloc(sizeof(Code));
1904    //codes = eina_list_append(codes, cd);
1905 
1906    _mempools_add(de);
1907 
1908    ed->file->collection_cache = eina_list_prepend(ed->file->collection_cache, pc);
1909    _edje_cache_coll_clean(ed->file);
1910 
1911    return EINA_TRUE;
1912 }
1913 
1914 EAPI Eina_Bool
edje_edit_group_del(Evas_Object * obj,const char * group_name)1915 edje_edit_group_del(Evas_Object *obj, const char *group_name)
1916 {
1917    Edje_Part_Collection_Directory_Entry *e, *e_del;
1918    Edje_Part_Collection *die = NULL;
1919    Edje_Part_Collection *g;
1920    Eina_List *l;
1921    Eet_File *eetf;
1922    char buf[64], **keys;
1923    int count;
1924 
1925    GET_ED_OR_RETURN(EINA_FALSE);
1926 
1927    if (strcmp(ed->group, group_name) == 0) return EINA_FALSE;
1928    e = eina_hash_find(ed->file->collection, group_name);
1929    if (!e) return EINA_FALSE;
1930    if (e->id == ed->collection->id) return EINA_FALSE;
1931    if (e->ref) return EINA_FALSE;
1932 
1933    _edje_edit_group_references_update(obj, group_name, NULL);
1934 
1935    EINA_LIST_FOREACH(ed->file->collection_cache, l, g)
1936      {
1937         if (strcmp(g->part, e->entry) == 0)
1938           {
1939              ed->file->collection_cache =
1940                eina_list_remove_list(ed->file->collection_cache, l);
1941              die = g;
1942              break;
1943           }
1944      }
1945 
1946    /* Remove collection/id from eet file */
1947    eetf = _edje_edit_eet_open(ed, EET_FILE_MODE_READ_WRITE);
1948    if (!eetf)
1949      return EINA_FALSE;
1950 
1951    snprintf(buf, sizeof(buf), "edje/collections/%d", e->id);
1952    eet_delete(eetf, buf);
1953    snprintf(buf, sizeof(buf), "edje/scripts/embryo/compiled/%d", e->id);
1954    eet_delete(eetf, buf);
1955    snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%d", e->id);
1956    eet_delete(eetf, buf);
1957    snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%d/*", e->id);
1958    keys = eet_list(eetf, buf, &count);
1959    if (keys)
1960      {
1961         do
1962           {
1963              count--;
1964              eet_delete(eetf, keys[count]);
1965           }
1966         while (count);
1967         free(keys);
1968      }
1969    _edje_edit_eet_close(eetf);
1970 
1971    l = NULL; g = NULL;
1972    /* Free Group and all it's Aliases */
1973    if (!e->group_alias)
1974      {
1975         EINA_LIST_FOREACH(ed->file->collection_cache, l, g)
1976           {
1977              if (e->id == g->id)
1978                {
1979                   ed->file->collection_cache =
1980                     eina_list_remove_list(ed->file->collection_cache, l);
1981                   e_del = eina_hash_find(ed->file->collection, g->part);
1982                   eina_hash_del(ed->file->collection, g->part, e_del);
1983                   _edje_collection_free(ed->file, g, e_del);
1984                }
1985           }
1986      }
1987    if (die) _edje_collection_free(ed->file, die, e);
1988    eina_hash_del(ed->file->collection, group_name, e);
1989 
1990    return EINA_TRUE;
1991 }
1992 
1993 EAPI Eina_Bool
edje_edit_group_exist(Evas_Object * obj,const char * group)1994 edje_edit_group_exist(Evas_Object *obj, const char *group)
1995 {
1996    GET_ED_OR_RETURN(EINA_FALSE);
1997 
1998    if (eina_hash_find(ed->file->collection, group))
1999      return EINA_TRUE;
2000    return EINA_FALSE;
2001 }
2002 
2003 EAPI Eina_Bool
edje_edit_group_name_set(Evas_Object * obj,const char * new_name)2004 edje_edit_group_name_set(Evas_Object *obj, const char *new_name)
2005 {
2006    Edje_Part_Collection_Directory_Entry *pce;
2007    Edje_Part_Collection *pc;
2008 
2009    GET_ED_OR_RETURN(EINA_FALSE);
2010 
2011    if (!new_name) return EINA_FALSE;
2012 
2013    pc = ed->collection;
2014 
2015    if (!strcmp(pc->part, new_name)) return EINA_TRUE;
2016 
2017    if (edje_edit_group_exist(obj, new_name)) return EINA_FALSE;
2018 
2019    _edje_edit_group_references_update(obj, pc->part, new_name);
2020 
2021    //printf("Set name of current group: %s [id: %d][new name: %s]\n",
2022    // pc->part, pc->id, new_name);
2023 
2024    //if (pc->part && ed->file->free_strings) eina_stringshare_del(pc->part); TODO FIXME
2025    pce = eina_hash_find(ed->file->collection, pc->part);
2026 
2027    eina_hash_move(ed->file->collection, pce->entry, new_name);
2028 
2029    pce->entry = eina_stringshare_add(new_name);
2030    pc->part = pce->entry;
2031    eina_stringshare_replace(&ed->group, new_name);
2032 
2033    return EINA_TRUE;
2034 }
2035 
2036 #define FUNC_GROUP_ACCESSOR(Class, Value)                           \
2037   EAPI int                                                          \
2038   edje_edit_group_##Class##_##Value##_get(Evas_Object * obj)        \
2039   {                                                                 \
2040      GET_ED_OR_RETURN(-1);                                          \
2041      if (!ed->collection) return -1;                                \
2042      return ed->collection->prop.Class.Value;                       \
2043   }                                                                 \
2044   EAPI Eina_Bool                                                    \
2045   edje_edit_group_##Class##_##Value##_set(Evas_Object * obj, int v) \
2046   {                                                                 \
2047      GET_ED_OR_RETURN(EINA_FALSE);                                  \
2048      if (!ed->collection) return EINA_FALSE;                        \
2049      if (v < 0) return EINA_FALSE;                                  \
2050      ed->collection->prop.Class.Value = v;                          \
2051      return EINA_TRUE;                                              \
2052   }
2053 
2054 FUNC_GROUP_ACCESSOR(min, w);
2055 FUNC_GROUP_ACCESSOR(min, h);
2056 FUNC_GROUP_ACCESSOR(max, w);
2057 FUNC_GROUP_ACCESSOR(max, h);
2058 
2059 EAPI unsigned char
edje_edit_group_orientation_get(Evas_Object * obj)2060 edje_edit_group_orientation_get(Evas_Object *obj)
2061 {
2062    GET_ED_OR_RETURN(-1);
2063    if (!ed->collection) return -1;
2064    return ed->collection->prop.orientation;
2065 }
2066 
2067 EAPI Eina_Bool
edje_edit_group_orientation_set(Evas_Object * obj,unsigned char orient)2068 edje_edit_group_orientation_set(Evas_Object *obj, unsigned char orient)
2069 {
2070    GET_ED_OR_RETURN(EINA_FALSE);
2071    if (!ed->collection) return EINA_FALSE;
2072    if (orient > 2) return EINA_FALSE;
2073    ed->collection->prop.orientation = orient;
2074    return EINA_TRUE;
2075 }
2076 
2077 EAPI Eina_Bool
edje_edit_group_broadcast_signal_get(Evas_Object * obj)2078 edje_edit_group_broadcast_signal_get(Evas_Object *obj)
2079 {
2080    GET_ED_OR_RETURN(EINA_TRUE);
2081    if (!ed->collection) return EINA_TRUE;
2082    return ed->collection->broadcast_signal;
2083 }
2084 
2085 EAPI Eina_Bool
edje_edit_group_broadcast_signal_set(Evas_Object * obj,Eina_Bool bs)2086 edje_edit_group_broadcast_signal_set(Evas_Object *obj, Eina_Bool bs)
2087 {
2088    GET_ED_OR_RETURN(EINA_FALSE);
2089    if (!ed->collection) return EINA_FALSE;
2090    ed->collection->broadcast_signal = bs ? 1 : 0;
2091    return EINA_TRUE;
2092 }
2093 
2094 #define LIMITS(TYPE)                                                                     \
2095   EAPI Eina_List *                                                                       \
2096   edje_edit_group_limits_##TYPE##_list_get(Evas_Object * obj)                            \
2097   {                                                                                      \
2098      Eina_List *limits = NULL;                                                           \
2099      unsigned int i;                                                                     \
2100      Edje_Edit_Limit *lim;                                                               \
2101                                                                                          \
2102      GET_ED_OR_RETURN(NULL);                                                             \
2103                                                                                          \
2104      if (!ed->file || !ed->collection)                                                   \
2105        return NULL;                                                                      \
2106      for (i = 0; i < ed->collection->limits.TYPE##_count; i++)                           \
2107        {                                                                                 \
2108           lim = malloc(sizeof(Edje_Edit_Limit));                                         \
2109           lim->name = eina_stringshare_add(ed->collection->limits.TYPE[i]->name);        \
2110           lim->value = ed->collection->limits.TYPE[i]->value;                            \
2111           limits = eina_list_append(limits, &lim);                                       \
2112        }                                                                                 \
2113                                                                                          \
2114      return limits;                                                                      \
2115   }                                                                                      \
2116                                                                                          \
2117   EAPI Eina_Bool                                                                         \
2118   edje_edit_group_limits_##TYPE##_del(Evas_Object * obj, const char *name, int value)    \
2119   {                                                                                      \
2120      unsigned int i;                                                                     \
2121      unsigned int new_count;                                                             \
2122                                                                                          \
2123      if ((!name) || (value < 1))                                                         \
2124        return EINA_FALSE;                                                                \
2125      GET_ED_OR_RETURN(EINA_FALSE);                                                       \
2126      GET_EED_OR_RETURN(EINA_FALSE);                                                      \
2127                                                                                          \
2128      new_count = ed->collection->limits.TYPE##_count - 1;                                \
2129      for (i = 0; i < ed->collection->limits.TYPE##_count; i++)                           \
2130        if ((ed->collection->limits.TYPE[i]->value == value)                              \
2131            && (!strcmp(ed->collection->limits.TYPE[i]->name, name)))                     \
2132          {                                                                               \
2133             _edje_if_string_free(ed, &ed->collection->limits.TYPE[i]->name);             \
2134             free(ed->collection->limits.TYPE[i]);                                        \
2135             if (i < new_count)                                                           \
2136               {                                                                          \
2137                  ed->collection->limits.TYPE[i] =                                        \
2138                    ed->collection->limits.TYPE[ed->collection->limits.TYPE##_count - 1]; \
2139               }                                                                          \
2140             ed->collection->limits.TYPE = realloc(ed->collection->limits.TYPE,           \
2141                                                   new_count * sizeof(Edje_Limit *));     \
2142             --ed->collection->limits.TYPE##_count;                                       \
2143             _edje_edit_flag_script_dirty(eed, EINA_TRUE);                                \
2144                                                                                          \
2145             return EINA_TRUE;                                                            \
2146          }                                                                               \
2147      return EINA_FALSE;                                                                  \
2148   }                                                                                      \
2149                                                                                          \
2150   EAPI Eina_Bool                                                                         \
2151   edje_edit_group_limits_##TYPE##_add(Evas_Object * obj, const char *name, int value)    \
2152   {                                                                                      \
2153      unsigned int i;                                                                     \
2154      unsigned int new_count;                                                             \
2155                                                                                          \
2156      if ((!name) || (value < 1))                                                         \
2157        return EINA_FALSE;                                                                \
2158      GET_ED_OR_RETURN(EINA_FALSE);                                                       \
2159                                                                                          \
2160      for (i = 0; i < ed->collection->limits.TYPE##_count; i++)                           \
2161        if ((ed->collection->limits.TYPE[i]->value == value)                              \
2162            && (!strcmp(ed->collection->limits.TYPE[i]->name, name)))                     \
2163          {                                                                               \
2164             return EINA_FALSE;                                                           \
2165          }                                                                               \
2166      new_count = ed->collection->limits.TYPE##_count + 1;                                \
2167      ed->collection->limits.TYPE = realloc(ed->collection->limits.TYPE,                  \
2168                                            new_count * sizeof(Edje_Limit *));            \
2169      ed->collection->limits.TYPE[new_count - 1] = malloc(sizeof(Edje_Limit));            \
2170      ed->collection->limits.TYPE[new_count - 1]->name = eina_stringshare_add(name);      \
2171      ed->collection->limits.TYPE[new_count - 1]->value = value;                          \
2172      ++ed->collection->limits.TYPE##_count;                                              \
2173      return EINA_TRUE;                                                                   \
2174   }
2175 
2176 LIMITS(vertical);
2177 LIMITS(horizontal);
2178 
2179 EAPI void
edje_edit_limits_list_free(Eina_List * list)2180 edje_edit_limits_list_free(Eina_List *list)
2181 {
2182    Edje_Edit_Limit *lim = eina_list_data_get(list);
2183    Edje_Edit_Limit *item;
2184    EINA_LIST_FREE(list, item)
2185      eina_stringshare_del(item->name);
2186    free(lim);
2187 }
2188 
2189 /****************/
2190 /*  ALIAS  API  */
2191 /****************/
2192 
2193 EAPI Eina_List *
edje_edit_group_aliases_get(Evas_Object * obj,const char * group_name)2194 edje_edit_group_aliases_get(Evas_Object *obj, const char *group_name)
2195 {
2196    Eina_Iterator *i;
2197    Edje_Part_Collection_Directory_Entry *e;
2198    Edje_Part_Collection_Directory_Entry *d;
2199    Eina_List *alias_list = NULL;
2200 
2201    GET_ED_OR_RETURN(NULL);
2202    if (!ed->file || !ed->file->collection)
2203      return NULL;
2204 
2205    e = eina_hash_find(ed->file->collection, group_name);
2206    if (!e) return NULL;
2207 
2208    i = eina_hash_iterator_data_new(ed->file->collection);
2209    EINA_ITERATOR_FOREACH(i, d)
2210      {
2211         if ((e->id == d->id) && (d->group_alias))
2212           alias_list = eina_list_append(alias_list, eina_stringshare_add(d->entry));
2213      }
2214    eina_iterator_free(i);
2215 
2216    return alias_list;
2217 }
2218 
2219 EAPI Eina_Bool
edje_edit_group_alias_is(Evas_Object * obj,const char * alias_name)2220 edje_edit_group_alias_is(Evas_Object *obj, const char *alias_name)
2221 {
2222    Edje_Part_Collection_Directory_Entry *e;
2223 
2224    GET_ED_OR_RETURN(EINA_FALSE);
2225    if (!ed->file || !ed->file->collection)
2226      return EINA_FALSE;
2227 
2228    e = eina_hash_find(ed->file->collection, alias_name);
2229    if (!e) return EINA_FALSE;
2230 
2231    return e->group_alias;
2232 }
2233 
2234 EAPI const char *
edje_edit_group_aliased_get(Evas_Object * obj,const char * alias_name)2235 edje_edit_group_aliased_get(Evas_Object *obj, const char *alias_name)
2236 {
2237    Eina_Iterator *i;
2238    Edje_Part_Collection_Directory_Entry *e;
2239    Edje_Part_Collection_Directory_Entry *d;
2240    const char *group_name = NULL;
2241 
2242    GET_ED_OR_RETURN(NULL);
2243    if (!ed->file || !ed->file->collection)
2244      return NULL;
2245 
2246    e = eina_hash_find(ed->file->collection, alias_name);
2247    if (!e) return NULL;
2248    if (!e->group_alias) return eina_stringshare_add(alias_name);
2249 
2250    i = eina_hash_iterator_data_new(ed->file->collection);
2251    EINA_ITERATOR_FOREACH(i, d)
2252      {
2253         if ((e->id == d->id) && (!d->group_alias))
2254           {
2255              group_name = d->entry;
2256              break;
2257           }
2258      }
2259    eina_iterator_free(i);
2260 
2261    return eina_stringshare_add(group_name);
2262 }
2263 
2264 EAPI Eina_Bool
edje_edit_group_alias_add(Evas_Object * obj,const char * group_name,const char * alias_name)2265 edje_edit_group_alias_add(Evas_Object *obj, const char *group_name, const char *alias_name)
2266 {
2267    Edje_Part_Collection_Directory_Entry *e;
2268    Edje_Part_Collection_Directory_Entry *de;
2269 
2270    GET_ED_OR_RETURN(EINA_FALSE);
2271 
2272    if (!ed->file || !ed->file->collection)
2273      return EINA_FALSE;
2274 
2275    /* check if a group with the same alias already exists */
2276    if (eina_hash_find(ed->file->collection, alias_name))
2277      return EINA_FALSE;
2278    /* check if a group that is being aliased is really exists */
2279    e = eina_hash_find(ed->file->collection, group_name);
2280    if (!e) return EINA_FALSE;
2281    /* check that a group that is being aliased is not an alias */
2282    if (e->group_alias) return EINA_FALSE;
2283 
2284    /* Create structs */
2285    de = _alloc(sizeof(Edje_Part_Collection_Directory_Entry));
2286    if (!de) return EINA_FALSE;
2287 
2288    /* Init Edje_Part_Collection_Directory_Entry */
2289    de->id = e->id;
2290    de->entry = eina_stringshare_add(alias_name);
2291    de->group_alias = EINA_TRUE;
2292 
2293    memcpy(&de->count, &e->count, sizeof (de->count));
2294    eina_hash_direct_add(ed->file->collection, de->entry, de);
2295 
2296    _mempools_add(de);
2297 
2298    return EINA_TRUE;
2299 }
2300 
2301 /***************/
2302 /*  DATA API   */
2303 /***************/
2304 
2305 EAPI Eina_List *
edje_edit_group_data_list_get(Evas_Object * obj)2306 edje_edit_group_data_list_get(Evas_Object *obj)
2307 {
2308    Eina_Iterator *it;
2309    Eina_List *datas = NULL;
2310    const char *key;
2311 
2312    GET_ED_OR_RETURN(NULL);
2313 
2314    if (!ed->file || !ed->collection || !ed->collection->data)
2315      return NULL;
2316 
2317    it = eina_hash_iterator_key_new(ed->collection->data);
2318    if (!it) return NULL;
2319 
2320    EINA_ITERATOR_FOREACH(it, key)
2321      datas = eina_list_append(datas, eina_stringshare_add(key));
2322 
2323    eina_iterator_free(it);
2324 
2325    return datas;
2326 }
2327 
2328 EAPI Eina_List *
edje_edit_data_list_get(Evas_Object * obj)2329 edje_edit_data_list_get(Evas_Object *obj)
2330 {
2331    Eina_Iterator *i;
2332    Eina_List *datas = NULL;
2333    const char *key;
2334 
2335    GET_ED_OR_RETURN(NULL);
2336 
2337    if (!ed->file || !ed->file->data)
2338      return NULL;
2339 
2340    i = eina_hash_iterator_key_new(ed->file->data);
2341 
2342    EINA_ITERATOR_FOREACH(i, key)
2343      datas = eina_list_append(datas, eina_stringshare_add(key));
2344 
2345    eina_iterator_free(i);
2346 
2347    return datas;
2348 }
2349 
2350 EAPI Eina_Bool
edje_edit_group_data_add(Evas_Object * obj,const char * key,const char * value)2351 edje_edit_group_data_add(Evas_Object *obj, const char *key, const char *value)
2352 {
2353    Edje_String *es;
2354 
2355    GET_ED_OR_RETURN(EINA_FALSE);
2356 
2357    if (!key || !ed->file || !ed->collection)
2358      return EINA_FALSE;
2359 
2360    if (!ed->collection->data)
2361      ed->collection->data = eina_hash_string_small_new(NULL);
2362 
2363    if (eina_hash_find(ed->collection->data, key))
2364      return EINA_FALSE;
2365 
2366    es = calloc(1, sizeof(Edje_String));
2367    if (!es)
2368      return EINA_FALSE;
2369    es->str = eina_stringshare_add(value);
2370 
2371    if (!eina_hash_add(ed->collection->data, key, es))
2372      {
2373         eina_stringshare_del(es->str);
2374         free(es);
2375         return EINA_FALSE;
2376      }
2377    return EINA_TRUE;
2378 }
2379 
2380 EAPI Eina_Bool
edje_edit_data_add(Evas_Object * obj,const char * itemname,const char * value)2381 edje_edit_data_add(Evas_Object *obj, const char *itemname, const char *value)
2382 {
2383    Edje_String *es;
2384 
2385    GET_ED_OR_RETURN(EINA_FALSE);
2386 
2387    if (!itemname || !ed->file)
2388      return EINA_FALSE;
2389 
2390    if (!ed->file->data)
2391      ed->file->data = eina_hash_string_small_new(NULL);
2392 
2393    if (eina_hash_find(ed->file->data, itemname))
2394      return EINA_FALSE;
2395 
2396    es = calloc(1, sizeof(Edje_String));
2397    if (!es)
2398      return EINA_FALSE;
2399    es->str = eina_stringshare_add(value);
2400 
2401    if (!eina_hash_add(ed->file->data, itemname, es))
2402      {
2403         eina_stringshare_del(es->str);
2404         free(es);
2405         return EINA_FALSE;
2406      }
2407    return EINA_TRUE;
2408 }
2409 
2410 EAPI Eina_Bool
edje_edit_group_data_del(Evas_Object * obj,const char * key)2411 edje_edit_group_data_del(Evas_Object *obj, const char *key)
2412 {
2413    Edje_String *value;
2414 
2415    GET_ED_OR_RETURN(EINA_FALSE);
2416 
2417    if (!key || !ed->file || !ed->collection)
2418      return EINA_FALSE;
2419 
2420    value = eina_hash_find(ed->collection->data, key);
2421    if (!value) return EINA_FALSE;
2422 
2423    eina_hash_del(ed->collection->data, key, value);
2424    _edje_if_string_free(ed, &value->str);
2425    free(value);
2426 
2427    return EINA_TRUE;
2428 }
2429 
2430 EAPI Eina_Bool
edje_edit_data_del(Evas_Object * obj,const char * itemname)2431 edje_edit_data_del(Evas_Object *obj, const char *itemname)
2432 {
2433    Edje_String *value;
2434 
2435    GET_ED_OR_RETURN(EINA_FALSE);
2436 
2437    if (!itemname || !ed->file || !ed->file->data)
2438      return 0;
2439 
2440    value = eina_hash_find(ed->file->data, itemname);
2441    if (!value)
2442      return EINA_FALSE;
2443 
2444    eina_hash_del(ed->file->data, itemname, value);
2445    _edje_if_string_free(ed, &value->str);
2446    free(value);
2447 
2448    return EINA_TRUE;
2449 }
2450 
2451 EAPI const char *
edje_edit_group_data_value_get(Evas_Object * obj,const char * key)2452 edje_edit_group_data_value_get(Evas_Object *obj, const char *key)
2453 {
2454    Edje_String *value;
2455 
2456    GET_ED_OR_RETURN(NULL);
2457 
2458    if (!key || !ed->file || !ed->collection)
2459      return NULL;
2460 
2461    value = eina_hash_find(ed->collection->data, key);
2462    if (!value)
2463      return NULL;
2464 
2465    return eina_stringshare_add(edje_string_get(value));
2466 }
2467 
2468 EAPI const char *
edje_edit_data_value_get(Evas_Object * obj,const char * itemname)2469 edje_edit_data_value_get(Evas_Object *obj, const char *itemname)
2470 {
2471    Edje_String *value;
2472 
2473    GET_ED_OR_RETURN(NULL);
2474 
2475    if (!itemname || !ed->file || !ed->file->data)
2476      return NULL;
2477 
2478    value = eina_hash_find(ed->file->data, itemname);
2479    if (!value)
2480      return NULL;
2481 
2482    return eina_stringshare_add(edje_string_get(value));
2483 }
2484 
2485 EAPI Eina_Bool
edje_edit_group_data_value_set(Evas_Object * obj,const char * key,const char * value)2486 edje_edit_group_data_value_set(Evas_Object *obj, const char *key, const char *value)
2487 {
2488    Edje_String *es;
2489 
2490    GET_ED_OR_RETURN(EINA_FALSE);
2491 
2492    if (!key || !value || !ed->file || !ed->collection)
2493      return EINA_FALSE;
2494 
2495    es = eina_hash_find(ed->collection->data, key);
2496    if (es)
2497      {
2498         _edje_if_string_replace(ed, &es->str, value);
2499         es->id = 0;
2500         return EINA_TRUE;
2501      }
2502 
2503    return EINA_FALSE;
2504 }
2505 
2506 EAPI Eina_Bool
edje_edit_data_value_set(Evas_Object * obj,const char * itemname,const char * value)2507 edje_edit_data_value_set(Evas_Object *obj, const char *itemname, const char *value)
2508 {
2509    Edje_String *es;
2510 
2511    GET_ED_OR_RETURN(EINA_FALSE);
2512 
2513    if (!itemname || !value || !ed->file || !ed->file->data)
2514      return EINA_FALSE;
2515 
2516    es = eina_hash_find(ed->file->data, itemname);
2517    if (es)
2518      {
2519         _edje_if_string_replace(ed, &es->str, value);
2520         es->id = 0;
2521         return EINA_TRUE;
2522      }
2523    return EINA_FALSE;
2524 }
2525 
2526 EAPI Eina_Bool
edje_edit_group_data_name_set(Evas_Object * obj,const char * key,const char * new_key)2527 edje_edit_group_data_name_set(Evas_Object *obj, const char *key, const char *new_key)
2528 {
2529    GET_ED_OR_RETURN(EINA_FALSE);
2530 
2531    if (!key || !new_key || !ed->file || !ed->collection)
2532      {
2533         return EINA_FALSE;
2534      }
2535 
2536    return eina_hash_move(ed->collection->data, key, new_key);
2537 }
2538 
2539 EAPI Eina_Bool
edje_edit_data_name_set(Evas_Object * obj,const char * itemname,const char * newname)2540 edje_edit_data_name_set(Evas_Object *obj, const char *itemname, const char *newname)
2541 {
2542    GET_ED_OR_RETURN(EINA_FALSE);
2543 
2544    if (!itemname || !newname || !ed->file || !ed->file->data)
2545      return EINA_FALSE;
2546 
2547    return eina_hash_move(ed->file->data, itemname, newname);
2548 }
2549 
2550 /***********************/
2551 /*  COLOR CLASSES API  */
2552 /***********************/
2553 
2554 EAPI Eina_List *
edje_edit_color_classes_list_get(Evas_Object * obj)2555 edje_edit_color_classes_list_get(Evas_Object *obj)
2556 {
2557    Eina_List *classes = NULL;
2558    Eina_List *l;
2559    Edje_Color_Class *cc;
2560 
2561    GET_ED_OR_RETURN(NULL);
2562 
2563    if (!ed->file || !ed->file->color_classes)
2564      return NULL;
2565    //printf("GET CLASSES LIST %d %d\n", eina_list_count(ed->color_classes), eina_list_count(ed->file->color_classes));
2566    EINA_LIST_FOREACH(ed->file->color_classes, l, cc)
2567      classes = eina_list_append(classes, eina_stringshare_add(cc->name));
2568 
2569    return classes;
2570 }
2571 
2572 EAPI Eina_Bool
edje_edit_color_class_colors_get(Evas_Object * obj,const char * class_name,int * r,int * g,int * b,int * a,int * r2,int * g2,int * b2,int * a2,int * r3,int * g3,int * b3,int * a3)2573 edje_edit_color_class_colors_get(Evas_Object *obj, const char *class_name, int *r, int *g, int *b, int *a, int *r2, int *g2, int *b2, int *a2, int *r3, int *g3, int *b3, int *a3)
2574 {
2575    Eina_List *l;
2576    Edje_Color_Class *cc;
2577 
2578    GET_ED_OR_RETURN(EINA_FALSE);
2579 
2580    if (!ed->file || !ed->file->color_classes)
2581      return EINA_FALSE;
2582 
2583    EINA_LIST_FOREACH(ed->file->color_classes, l, cc)
2584      if (!strcmp(cc->name, class_name))
2585        {
2586           if (r) *r = cc->r;
2587           if (g) *g = cc->g;
2588           if (b) *b = cc->b;
2589           if (a) *a = cc->a;
2590 
2591           if (r2) *r2 = cc->r2;
2592           if (g2) *g2 = cc->g2;
2593           if (b2) *b2 = cc->b2;
2594           if (a2) *a2 = cc->a2;
2595 
2596           if (r3) *r3 = cc->r3;
2597           if (g3) *g3 = cc->g3;
2598           if (b3) *b3 = cc->b3;
2599           if (a3) *a3 = cc->a3;
2600 
2601           return EINA_TRUE;
2602        }
2603    return EINA_FALSE;
2604 }
2605 
2606 EAPI Eina_Bool
edje_edit_color_class_colors_set(Evas_Object * obj,const char * class_name,int r,int g,int b,int a,int r2,int g2,int b2,int a2,int r3,int g3,int b3,int a3)2607 edje_edit_color_class_colors_set(Evas_Object *obj, const char *class_name, int r, int g, int b, int a, int r2, int g2, int b2, int a2, int r3, int g3, int b3, int a3)
2608 {
2609    Eina_List *l;
2610    Edje_Color_Class *cc;
2611 
2612    GET_ED_OR_RETURN(EINA_FALSE);
2613 
2614    if (!ed->file || !ed->file->color_classes)
2615      return EINA_FALSE;
2616 
2617    EINA_LIST_FOREACH(ed->file->color_classes, l, cc)
2618      if (!strcmp(cc->name, class_name))
2619        {
2620           if (r > -1) cc->r = r;
2621           if (g > -1) cc->g = g;
2622           if (b > -1) cc->b = b;
2623           if (a > -1) cc->a = a;
2624 
2625           if (r2 > -1) cc->r2 = r2;
2626           if (g2 > -1) cc->g2 = g2;
2627           if (b2 > -1) cc->b2 = b2;
2628           if (a2 > -1) cc->a2 = a2;
2629 
2630           if (r3 > -1) cc->r3 = r3;
2631           if (g3 > -1) cc->g3 = g3;
2632           if (b3 > -1) cc->b3 = b3;
2633           if (a3 > -1) cc->a3 = a3;
2634 
2635           return EINA_TRUE;
2636        }
2637    return EINA_FALSE;
2638 }
2639 
2640 EAPI Eina_Stringshare *
edje_edit_color_class_description_get(Evas_Object * obj,const char * class_name)2641 edje_edit_color_class_description_get(Evas_Object *obj, const char *class_name)
2642 {
2643    Eina_List *l;
2644    Edje_Color_Class *cc;
2645 
2646    GET_ED_OR_RETURN(NULL);
2647    EINA_SAFETY_ON_NULL_RETURN_VAL(class_name, NULL);
2648 
2649    if (!ed->file || !ed->file->color_classes)
2650      return NULL;
2651    EINA_LIST_FOREACH(ed->file->color_classes, l, cc)
2652      if (eina_streq(cc->name, class_name))
2653        return cc->desc;
2654    return NULL;
2655 }
2656 
2657 EAPI Eina_Bool
edje_edit_color_class_description_set(Evas_Object * obj,const char * class_name,const char * desc)2658 edje_edit_color_class_description_set(Evas_Object *obj, const char *class_name, const char *desc)
2659 {
2660    Eina_List *l;
2661    Edje_Color_Class *cc;
2662 
2663    GET_ED_OR_RETURN(EINA_FALSE);
2664    EINA_SAFETY_ON_NULL_RETURN_VAL(class_name, EINA_FALSE);
2665 
2666    if (!ed->file || !ed->file->color_classes)
2667      return EINA_FALSE;
2668    EINA_LIST_FOREACH(ed->file->color_classes, l, cc)
2669      if (eina_streq(cc->name, class_name))
2670        {
2671           eina_stringshare_replace(&cc->desc, desc);
2672           return EINA_TRUE;
2673        }
2674    return EINA_FALSE;
2675 }
2676 
2677 EAPI Eina_Bool
edje_edit_color_class_add(Evas_Object * obj,const char * name)2678 edje_edit_color_class_add(Evas_Object *obj, const char *name)
2679 {
2680    Eina_List *l;
2681    Edje_Color_Class *c;
2682    Edje_Color_Class *cc;
2683 
2684    GET_ED_OR_RETURN(EINA_FALSE);
2685 
2686    if (!name || !ed->file)
2687      return EINA_FALSE;
2688 
2689    EINA_LIST_FOREACH(ed->file->color_classes, l, cc)
2690      if (strcmp(cc->name, name) == 0)
2691        return EINA_FALSE;
2692 
2693    c = _alloc(sizeof(Edje_Color_Class));
2694    if (!c) return EINA_FALSE;
2695 
2696    c->name = (char *)eina_stringshare_add(name);
2697    c->r = c->g = c->b = c->a = 255;
2698    c->r2 = c->g2 = c->b2 = c->a2 = 255;
2699    c->r3 = c->g3 = c->b3 = c->a3 = 255;
2700 
2701    ed->file->color_classes = eina_list_append(ed->file->color_classes, c);
2702 
2703    return EINA_TRUE;
2704 }
2705 
2706 EAPI Eina_Bool
edje_edit_color_class_del(Evas_Object * obj,const char * name)2707 edje_edit_color_class_del(Evas_Object *obj, const char *name)
2708 {
2709    Eina_List *l;
2710    Edje_Color_Class *cc;
2711 
2712    GET_ED_OR_RETURN(EINA_FALSE);
2713 
2714    if (!name || !ed->file || !ed->file->color_classes)
2715      return EINA_FALSE;
2716 
2717    EINA_LIST_FOREACH(ed->file->color_classes, l, cc)
2718      if (strcmp(cc->name, name) == 0)
2719        {
2720           _edje_if_string_free(ed, &cc->name);
2721           ed->file->color_classes = eina_list_remove(ed->file->color_classes, cc);
2722           free(cc);
2723           return EINA_TRUE;
2724        }
2725    return EINA_FALSE;
2726 }
2727 
2728 EAPI Eina_Bool
edje_edit_color_class_name_set(Evas_Object * obj,const char * name,const char * newname)2729 edje_edit_color_class_name_set(Evas_Object *obj, const char *name, const char *newname)
2730 {
2731    Eina_List *l;
2732    Edje_Color_Class *cc;
2733 
2734    GET_ED_OR_RETURN(EINA_FALSE);
2735 
2736    if (!ed->file || !ed->file->color_classes)
2737      return EINA_FALSE;
2738 
2739    EINA_LIST_FOREACH(ed->file->color_classes, l, cc)
2740      if (!strcmp(cc->name, name))
2741        {
2742           _edje_if_string_replace(ed, &cc->name, newname);
2743           return EINA_TRUE;
2744        }
2745 
2746    return EINA_FALSE;
2747 }
2748 
2749 /*********************/
2750 /*  TEXT STYLES API  */
2751 /*********************/
2752 
2753 EAPI Eina_List *
edje_edit_styles_list_get(Evas_Object * obj)2754 edje_edit_styles_list_get(Evas_Object *obj)
2755 {
2756    Eina_List *styles = NULL;
2757    Eina_List *l;
2758    Edje_Style *s;
2759 
2760    GET_ED_OR_RETURN(NULL);
2761 
2762    if (!ed->file || !ed->file->styles)
2763      return NULL;
2764    //printf("GET STYLES LIST %d\n", eina_list_count(ed->file->styles));
2765    EINA_LIST_FOREACH(ed->file->styles, l, s)
2766      styles = eina_list_append(styles, eina_stringshare_add(s->name));
2767 
2768    return styles;
2769 }
2770 
2771 EAPI Eina_Bool
edje_edit_style_add(Evas_Object * obj,const char * style)2772 edje_edit_style_add(Evas_Object *obj, const char *style)
2773 {
2774    Edje_Style *s;
2775 
2776    GET_ED_OR_RETURN(EINA_FALSE);
2777    //printf("ADD STYLE '%s'\n", style);
2778 
2779    s = _edje_edit_style_get(ed, style);
2780    if (s) return EINA_FALSE;
2781 
2782    s = _alloc(sizeof(Edje_Style));
2783    if (!s) return EINA_FALSE;
2784    s->name = (char *)eina_stringshare_add(style);
2785    s->tags = NULL;
2786    s->style = NULL;
2787 
2788    ed->file->styles = eina_list_append(ed->file->styles, s);
2789    return EINA_TRUE;
2790 }
2791 
2792 EAPI Eina_Bool
edje_edit_style_del(Evas_Object * obj,const char * style)2793 edje_edit_style_del(Evas_Object *obj, const char *style)
2794 {
2795    Edje_Style *s;
2796 
2797    GET_ED_OR_RETURN(EINA_FALSE);
2798 
2799    s = _edje_edit_style_get(ed, style);
2800    if (!s) return EINA_FALSE;
2801 
2802    ed->file->styles = eina_list_remove(ed->file->styles, s);
2803 
2804    _edje_if_string_free(ed, (const char **)&s->name);
2805    evas_textblock_style_free(s->style);
2806    while (s->tags)
2807      {
2808         Edje_Style_Tag *t;
2809 
2810         t = s->tags->data;
2811 
2812         s->tags = eina_list_remove(s->tags, t);
2813         _edje_if_string_free(ed, &t->key);
2814         _edje_if_string_free(ed, &t->value);
2815         _edje_if_string_free(ed, &t->font);
2816         _edje_if_string_free(ed, &t->text_class);
2817         free(t);
2818      }
2819    free(s);
2820    return EINA_TRUE;
2821 }
2822 
2823 EAPI Eina_List *
edje_edit_style_tags_list_get(Evas_Object * obj,const char * style)2824 edje_edit_style_tags_list_get(Evas_Object *obj, const char *style)
2825 {
2826    Eina_List *tags = NULL;
2827    Eina_List *l;
2828    Edje_Style *s;
2829    Edje_Style_Tag *t;
2830 
2831    GET_ED_OR_RETURN(NULL);
2832    if (!ed->file || !ed->file->styles || !style)
2833      return NULL;
2834 
2835    s = _edje_edit_style_get(ed, style);
2836 
2837    //printf("GET STYLE TAG LIST %d\n", eina_list_count(s->tags));
2838    EINA_LIST_FOREACH(s->tags, l, t)
2839      tags = eina_list_append(tags, eina_stringshare_add(t->key));
2840 
2841    return tags;
2842 }
2843 
2844 EAPI Eina_Bool
edje_edit_style_tag_name_set(Evas_Object * obj,const char * style,const char * tag,const char * new_name)2845 edje_edit_style_tag_name_set(Evas_Object *obj, const char *style, const char *tag, const char *new_name)
2846 {
2847    Edje_Style_Tag *t;
2848 
2849    GET_ED_OR_RETURN(EINA_FALSE);
2850 
2851    if (!ed->file || !ed->file->styles || !style || !tag)
2852      return EINA_FALSE;
2853 
2854    t = _edje_edit_style_tag_get(ed, style, tag);
2855    if (!t) return EINA_FALSE;
2856    _edje_if_string_replace(ed, &t->key, new_name);
2857    return EINA_TRUE;
2858 }
2859 
2860 EAPI const char *
edje_edit_style_tag_value_get(Evas_Object * obj,const char * style,const char * tag)2861 edje_edit_style_tag_value_get(Evas_Object *obj, const char *style, const char *tag)
2862 {
2863    Edje_Style_Tag *t;
2864 
2865    GET_ED_OR_RETURN(NULL);
2866    //printf("GET TAG '%s' FOR STYLE '%s'\n", tag, style);
2867 
2868    if (!ed->file || !ed->file->styles || !style || !tag)
2869      return NULL;
2870 
2871    t = _edje_edit_style_tag_get(ed, style, tag);
2872    if (t && t->value)
2873      return eina_stringshare_add(t->value);
2874 
2875    return NULL;
2876 }
2877 
2878 EAPI Eina_Bool
edje_edit_style_tag_value_set(Evas_Object * obj,const char * style,const char * tag,const char * new_value)2879 edje_edit_style_tag_value_set(Evas_Object *obj, const char *style, const char *tag, const char *new_value)
2880 {
2881    Edje_Style_Tag *t;
2882 
2883    GET_ED_OR_RETURN(EINA_FALSE);
2884 
2885    if (!ed->file || !ed->file->styles || !style || !tag || !new_value)
2886      return EINA_FALSE;
2887 
2888    t = _edje_edit_style_tag_get(ed, style, tag);
2889    if (!t) return EINA_FALSE;
2890    _edje_if_string_replace(ed, &t->value, new_value);
2891    return EINA_TRUE;
2892 }
2893 
2894 EAPI Eina_Bool
edje_edit_style_tag_add(Evas_Object * obj,const char * style,const char * tag_name)2895 edje_edit_style_tag_add(Evas_Object *obj, const char *style, const char *tag_name)
2896 {
2897    Edje_Style *s;
2898    Edje_Style_Tag *t;
2899 
2900    GET_ED_OR_RETURN(EINA_FALSE);
2901    //printf("ADD TAG '%s' IN STYLE '%s'\n", tag_name, style);
2902 
2903    t = _edje_edit_style_tag_get(ed, style, tag_name);
2904    if (t) return EINA_FALSE;
2905    s = _edje_edit_style_get(ed, style);
2906    if (!s) return EINA_FALSE;
2907 
2908    t = _alloc(sizeof(Edje_Style_Tag));
2909    if (!t) return EINA_FALSE;
2910    t->key = eina_stringshare_add(tag_name);
2911    t->value = NULL;
2912    t->font = NULL;
2913    t->text_class = NULL;
2914 
2915    s->tags = eina_list_append(s->tags, t);
2916    return EINA_TRUE;
2917 }
2918 
2919 EAPI Eina_Bool
edje_edit_style_tag_del(Evas_Object * obj,const char * style,const char * tag)2920 edje_edit_style_tag_del(Evas_Object *obj, const char *style, const char *tag)
2921 {
2922    Edje_Style *s;
2923    Edje_Style_Tag *t;
2924 
2925    GET_ED_OR_RETURN(EINA_FALSE);
2926    if (!ed->file || !ed->file->styles || !style || !tag )
2927      return EINA_FALSE;
2928 
2929    s = _edje_edit_style_get(ed, style);
2930    t = _edje_edit_style_tag_get(ed, style, tag);
2931    if (!s || !t) return EINA_FALSE;
2932 
2933    s->tags = eina_list_remove(s->tags, t);
2934    _edje_if_string_free(ed, &t->key);
2935    _edje_if_string_free(ed, &t->value);
2936    _edje_if_string_free(ed, &t->font);
2937    _edje_if_string_free(ed, &t->text_class);
2938    free(t);
2939    t = NULL;
2940    return EINA_TRUE;
2941 }
2942 
2943 /*******************/
2944 /*  EXTERNALS API  */
2945 /*******************/
2946 
2947 EAPI Eina_List *
edje_edit_externals_list_get(Evas_Object * obj)2948 edje_edit_externals_list_get(Evas_Object *obj)
2949 {
2950    Eina_List *externals = NULL;
2951    unsigned int i;
2952 
2953    GET_ED_OR_RETURN(NULL);
2954 
2955    if (!ed->file || !ed->file->external_dir)
2956      return NULL;
2957    //printf("GET STYLES LIST %d\n", eina_list_count(ed->file->styles));
2958    for (i = 0; i < ed->file->external_dir->entries_count; ++i)
2959      externals = eina_list_append(externals,
2960                                   eina_stringshare_add(ed->file->external_dir->entries[i].entry));
2961 
2962    return externals;
2963 }
2964 
2965 EAPI Eina_Bool
edje_edit_external_add(Evas_Object * obj,const char * external)2966 edje_edit_external_add(Evas_Object *obj, const char *external)
2967 {
2968    Edje_External_Directory_Entry *e;
2969    unsigned int freeid;
2970    unsigned int i;
2971 
2972    GET_ED_OR_RETURN(EINA_FALSE);
2973 
2974    e = _edje_edit_external_get(ed, external);
2975    if (e) return EINA_FALSE;
2976 
2977    if (!ed->file->external_dir)
2978      ed->file->external_dir = _alloc(sizeof(Edje_External_Directory));
2979    if (!ed->file->external_dir) return EINA_FALSE;
2980 
2981    for (i = 0; i < ed->file->external_dir->entries_count; ++i)
2982      if (!ed->file->external_dir->entries[i].entry)
2983        break;
2984 
2985    if (i == ed->file->external_dir->entries_count)
2986      {
2987         Edje_External_Directory_Entry *tmp;
2988         unsigned int max;
2989 
2990         max = ed->file->external_dir->entries_count + 1;
2991         tmp = realloc(ed->file->external_dir->entries,
2992                       sizeof (Edje_External_Directory_Entry) * max);
2993 
2994         if (!tmp) return EINA_FALSE;
2995 
2996         ed->file->external_dir->entries = tmp;
2997         freeid = ed->file->external_dir->entries_count;
2998         ed->file->external_dir->entries_count = max;
2999      }
3000    else
3001      freeid = i;
3002 
3003    ed->file->external_dir->entries[freeid].entry = (char *)eina_stringshare_add(external);
3004 
3005    return EINA_TRUE;
3006 }
3007 
3008 EAPI Eina_Bool
edje_edit_external_del(Evas_Object * obj,const char * external)3009 edje_edit_external_del(Evas_Object *obj, const char *external)
3010 {
3011    Edje_External_Directory_Entry *e;
3012 
3013    GET_ED_OR_RETURN(EINA_FALSE);
3014 
3015    e = _edje_edit_external_get(ed, external);
3016    if (!e) return EINA_FALSE;
3017 
3018    _edje_if_string_free(ed, &e->entry);
3019    e->entry = NULL;
3020 
3021    return EINA_TRUE;
3022 }
3023 
3024 /***************/
3025 /*  PARTS API  */
3026 /***************/
3027 
3028 EAPI Edje_Edit_Select_Mode
edje_edit_part_select_mode_get(Evas_Object * obj,const char * part)3029 edje_edit_part_select_mode_get(Evas_Object *obj, const char *part)
3030 {
3031    GET_RP_OR_RETURN(EINA_FALSE);
3032 
3033    if (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)
3034      return EINA_FALSE;
3035 
3036    return (Edje_Edit_Select_Mode)rp->part->select_mode;
3037 }
3038 
3039 EAPI Eina_Bool
edje_edit_part_select_mode_set(Evas_Object * obj,const char * part,Edje_Edit_Select_Mode mode)3040 edje_edit_part_select_mode_set(Evas_Object *obj, const char *part, Edje_Edit_Select_Mode mode)
3041 {
3042    if (mode > EDJE_EDIT_SELECT_MODE_EXPLICIT)
3043      return EINA_FALSE;
3044    GET_RP_OR_RETURN(EINA_FALSE);
3045 
3046    if (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)
3047      return EINA_FALSE;
3048 
3049    rp->part->select_mode = (unsigned char)mode;
3050    return EINA_TRUE;
3051 }
3052 
3053 EAPI Edje_Edit_Entry_Mode
edje_edit_part_entry_mode_get(Evas_Object * obj,const char * part)3054 edje_edit_part_entry_mode_get(Evas_Object *obj, const char *part)
3055 {
3056    GET_RP_OR_RETURN(EINA_FALSE);
3057 
3058    if (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)
3059      return EINA_FALSE;
3060 
3061    return (Edje_Edit_Entry_Mode)rp->part->entry_mode;
3062 }
3063 
3064 EAPI Eina_Bool
edje_edit_part_entry_mode_set(Evas_Object * obj,const char * part,Edje_Edit_Entry_Mode mode)3065 edje_edit_part_entry_mode_set(Evas_Object *obj, const char *part, Edje_Edit_Entry_Mode mode)
3066 {
3067    if (mode > EDJE_EDIT_ENTRY_MODE_PASSWORD)
3068      return EINA_FALSE;
3069    GET_RP_OR_RETURN(EINA_FALSE);
3070 
3071    if (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)
3072      return EINA_FALSE;
3073 
3074    rp->part->entry_mode = (unsigned char)mode;
3075    return EINA_TRUE;
3076 }
3077 
3078 EAPI Eina_List *
edje_edit_parts_list_get(Evas_Object * obj)3079 edje_edit_parts_list_get(Evas_Object *obj)
3080 {
3081    Eina_List *parts = NULL;
3082    unsigned short i;
3083 
3084    GET_ED_OR_RETURN(NULL);
3085 
3086    //printf("EE: Found %d parts\n", ed->table_parts_size);
3087 
3088    parts = NULL;
3089    for (i = 0; i < ed->table_parts_size; i++)
3090      {
3091         Edje_Real_Part *rp;
3092 
3093         rp = ed->table_parts[i];
3094         parts = eina_list_append(parts, eina_stringshare_add(rp->part->name));
3095      }
3096 
3097    return parts;
3098 }
3099 
3100 EAPI Eina_Bool
edje_edit_part_name_set(Evas_Object * obj,const char * part,const char * new_name)3101 edje_edit_part_name_set(Evas_Object *obj, const char *part, const char *new_name)
3102 {
3103    GET_EED_OR_RETURN(EINA_FALSE);
3104    GET_RP_OR_RETURN(EINA_FALSE);
3105 
3106    if (!new_name) return EINA_FALSE;
3107    if (!strcmp(part, new_name)) return EINA_TRUE;
3108    if (_edje_real_part_get(ed, new_name)) return EINA_FALSE;
3109 
3110    //printf("Set name of part: %s [new name: %s]\n", part, new_name);
3111 
3112    _edje_if_string_replace(ed, &rp->part->name, new_name);
3113 
3114    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
3115 
3116    return EINA_TRUE;
3117 }
3118 
3119 #define FUNC_PART_API_STRING(Value)                                                    \
3120   EAPI const char *                                                                    \
3121   edje_edit_part_api_##Value##_get(Evas_Object * obj, const char *part)                \
3122   {                                                                                    \
3123      GET_RP_OR_RETURN(NULL);                                                           \
3124      return eina_stringshare_add(rp->part->api.Value);                                 \
3125   }                                                                                    \
3126   EAPI Eina_Bool                                                                       \
3127   edje_edit_part_api_##Value##_set(Evas_Object * obj, const char *part, const char *s) \
3128   {                                                                                    \
3129      GET_RP_OR_RETURN(EINA_FALSE);                                                     \
3130      _edje_if_string_replace(ed, &rp->part->api.Value, s);                             \
3131      return EINA_TRUE;                                                                 \
3132   }
3133 
3134 FUNC_PART_API_STRING(name);
3135 FUNC_PART_API_STRING(description);
3136 
3137 static Eina_Bool
_edje_edit_real_part_add(Evas_Object * obj,const char * name,Edje_Part_Type type,const char * source)3138 _edje_edit_real_part_add(Evas_Object *obj, const char *name, Edje_Part_Type type, const char *source)
3139 {
3140    Edje_Part_Collection_Directory_Entry *ce;
3141    Edje_Part_Collection *pc;
3142    Edje_Part **tmp;
3143    Edje_Part *ep;
3144    Edje_Real_Part *rp;
3145    int id;
3146 
3147    GET_ED_OR_RETURN(EINA_FALSE);
3148 
3149    if (ed->table_parts_size == 0xffff) return EINA_FALSE;
3150    //printf("ADD PART: %s [type: %d]\n", name, type);
3151 
3152    /* Check if part already exists */
3153    if (_edje_real_part_get(ed, name))
3154      return EINA_FALSE;
3155 
3156    if (!ed->file) return EINA_FALSE;
3157 
3158    ce = eina_hash_find(ed->file->collection, ed->group);
3159 
3160    /* Alloc Edje_Part or return */
3161    ep = eina_mempool_malloc(ce->mp->mp.part, sizeof(Edje_Part));
3162    if (!ep) return EINA_FALSE;
3163    memset(ep, 0, sizeof(Edje_Part));
3164 
3165    /* Alloc Edje_Real_Part or return */
3166    rp = eina_mempool_malloc(_edje_real_part_mp, sizeof(Edje_Real_Part));
3167    if (!rp)
3168      {
3169         eina_mempool_free(ce->mp->mp.part, ep);
3170         return EINA_FALSE;
3171      }
3172    memset(rp, 0, sizeof(Edje_Real_Part));
3173 
3174    /* Init Edje_Part */
3175    pc = ed->collection;
3176 
3177    tmp = realloc(pc->parts, (pc->parts_count + 1) * sizeof (Edje_Part *));
3178    if (!tmp)
3179      {
3180         eina_mempool_free(ce->mp->mp.part, ep);
3181         eina_mempool_free(_edje_real_part_mp, rp);
3182         return EINA_FALSE;
3183      }
3184 
3185    id = pc->parts_count++;
3186 
3187    pc->parts = tmp;
3188    pc->parts[id] = ep;
3189 
3190    ep->id = id;
3191    ep->type = type;
3192    ep->name = eina_stringshare_add(name);
3193    ep->mouse_events = 1;
3194    ep->repeat_events = 0;
3195    ep->anti_alias = 1;
3196    ep->ignore_flags = EVAS_EVENT_FLAG_NONE;
3197    ep->mask_flags = EVAS_EVENT_FLAG_NONE;
3198    ep->pointer_mode = EVAS_OBJECT_POINTER_MODE_AUTOGRAB;
3199    ep->precise_is_inside = 0;
3200    ep->use_alternate_font_metrics = 0;
3201    ep->clip_to_id = -1;
3202    ep->dragable.confine_id = -1;
3203    ep->dragable.threshold_id = -1;
3204    ep->dragable.event_id = -1;
3205    if (source)
3206      ep->source = eina_stringshare_add(source);
3207 
3208    ep->default_desc = NULL;
3209    ep->other.desc = NULL;
3210    ep->other.desc_count = 0;
3211 
3212    /* Init Edje_Real_Part */
3213    _edje_ref(ed);
3214    rp->part = ep;
3215 
3216    if (ep->type == EDJE_PART_TYPE_RECTANGLE)
3217      rp->object = evas_object_rectangle_add(ed->base.evas);
3218    else if (ep->type == EDJE_PART_TYPE_VECTOR)
3219      {
3220         rp->type = EDJE_PART_TYPE_VECTOR;
3221         rp->object = evas_object_vg_add(ed->base.evas);
3222      }
3223    else if (ep->type == EDJE_PART_TYPE_IMAGE || ep->type == EDJE_PART_TYPE_PROXY)
3224      rp->object = evas_object_image_add(ed->base.evas);
3225    else if (ep->type == EDJE_PART_TYPE_TEXT)
3226      {
3227         rp->type = EDJE_RP_TYPE_TEXT;
3228         rp->typedata.text = calloc(1, sizeof(Edje_Real_Part_Text));
3229         _edje_text_part_on_add(ed, rp);
3230         rp->object = evas_object_text_add(ed->base.evas);
3231         evas_object_text_font_source_set(rp->object, ed->path);
3232      }
3233    else if (ep->type == EDJE_PART_TYPE_SWALLOW ||
3234             ep->type == EDJE_PART_TYPE_GROUP ||
3235             ep->type == EDJE_PART_TYPE_EXTERNAL)
3236      {
3237         rp->type = EDJE_RP_TYPE_SWALLOW;
3238         rp->typedata.swallow = calloc(1, sizeof(Edje_Real_Part_Swallow));
3239         rp->object = evas_object_rectangle_add(ed->base.evas);
3240         evas_object_color_set(rp->object, 0, 0, 0, 0);
3241         evas_object_pass_events_set(rp->object, 1);
3242         evas_object_pointer_mode_set(rp->object, EVAS_OBJECT_POINTER_MODE_NOGRAB);
3243      }
3244    else if (ep->type == EDJE_PART_TYPE_TEXTBLOCK)
3245      {
3246         rp->type = EDJE_RP_TYPE_TEXT;
3247         rp->typedata.text = calloc(1, sizeof(Edje_Real_Part_Text));
3248         rp->object = evas_object_textblock_add(ed->base.evas);
3249      }
3250    else if (ep->type == EDJE_PART_TYPE_BOX)
3251      {
3252         rp->type = EDJE_RP_TYPE_CONTAINER;
3253         rp->typedata.container = calloc(1, sizeof(Edje_Real_Part_Container));
3254         rp->object = evas_object_box_add(ed->base.evas);
3255         rp->typedata.container->anim = _edje_box_layout_anim_new(rp->object);
3256      }
3257    else if (ep->type == EDJE_PART_TYPE_TABLE)
3258      {
3259         rp->type = EDJE_RP_TYPE_CONTAINER;
3260         rp->typedata.container = calloc(1, sizeof(Edje_Real_Part_Container));
3261         rp->object = evas_object_table_add(ed->base.evas);
3262      }
3263    else if (ep->type != EDJE_PART_TYPE_SPACER)
3264      ERR("wrong part type %i!", ep->type);
3265    if (rp->object)
3266      {
3267         evas_object_show(rp->object);
3268         evas_object_smart_member_add(rp->object, ed->obj);
3269         evas_object_layer_set(rp->object, evas_object_layer_get(ed->obj));
3270         if (ep->type == EDJE_PART_TYPE_SWALLOW)
3271           {
3272              efl_parent_set(rp->object, ed->obj);
3273           }
3274         else if (ep->type != EDJE_PART_TYPE_GROUP)
3275           {
3276              if (ep->mouse_events)
3277                {
3278                   _edje_callbacks_add(rp->object, ed, rp);
3279                   if (ep->repeat_events)
3280                     evas_object_repeat_events_set(rp->object, 1);
3281 
3282                   if (ep->pointer_mode != EVAS_OBJECT_POINTER_MODE_AUTOGRAB)
3283                     evas_object_pointer_mode_set(rp->object, ep->pointer_mode);
3284                }
3285              else
3286                {
3287                   evas_object_pass_events_set(rp->object, 1);
3288                   evas_object_pointer_mode_set(rp->object,
3289                                                EVAS_OBJECT_POINTER_MODE_NOGRAB);
3290                }
3291              if (ep->precise_is_inside)
3292                evas_object_precise_is_inside_set(rp->object, 1);
3293           }
3294         if (ep->type == EDJE_PART_TYPE_EXTERNAL)
3295           {
3296              Evas_Object *child;
3297              child = _edje_external_type_add(source, evas_object_evas_get(ed->obj), ed->obj, NULL, name);
3298              if (child)
3299                _edje_real_part_swallow(ed, rp, child, EINA_TRUE);
3300           }
3301         evas_object_clip_set(rp->object, ed->base.clipper);
3302         evas_object_show(ed->base.clipper);
3303      }
3304 
3305    /* Update table_parts */
3306    ed->table_parts_size++;
3307    ed->table_parts = realloc(ed->table_parts,
3308                              sizeof(Edje_Real_Part *) * ed->table_parts_size);
3309 
3310    ed->table_parts[ep->id % ed->table_parts_size] = rp;
3311 
3312    /* Create default description */
3313    if (!edje_edit_state_add(obj, name, "default", 0.0))
3314      {
3315         _edje_if_string_free(ed, &ep->name);
3316         if (source)
3317           _edje_if_string_free(ed, &ep->source);
3318         eina_mempool_free(ce->mp->mp.part, ep);
3319         eina_mempool_free(_edje_real_part_mp, rp);
3320         return EINA_FALSE;
3321      }
3322    edje_edit_part_selected_state_set(obj, name, "default", 0.0);
3323 
3324    ce->count.part++;
3325 
3326    return EINA_TRUE;
3327 }
3328 
3329 EAPI Eina_Bool
edje_edit_part_add(Evas_Object * obj,const char * name,Edje_Part_Type type)3330 edje_edit_part_add(Evas_Object *obj, const char *name, Edje_Part_Type type)
3331 {
3332    if (type == EDJE_PART_TYPE_EXTERNAL)
3333      return EINA_FALSE;
3334    return _edje_edit_real_part_add(obj, name, type, NULL);
3335 }
3336 
3337 EAPI Eina_Bool
edje_edit_part_external_add(Evas_Object * obj,const char * name,const char * source)3338 edje_edit_part_external_add(Evas_Object *obj, const char *name, const char *source)
3339 {
3340    if (!source)
3341      return EINA_FALSE;
3342    return _edje_edit_real_part_add(obj, name, EDJE_PART_TYPE_EXTERNAL, source);
3343 }
3344 
3345 EAPI Eina_Bool
edje_edit_part_del(Evas_Object * obj,const char * part)3346 edje_edit_part_del(Evas_Object *obj, const char *part)
3347 {
3348    Edje_Part_Collection_Directory_Entry *ce;
3349    Edje_Part_Collection *pc;
3350    Edje_Part *ep;
3351    unsigned int k;
3352    unsigned int id;
3353    unsigned short i, j;
3354 
3355    GET_EED_OR_RETURN(EINA_FALSE);
3356    GET_RP_OR_RETURN(EINA_FALSE);
3357 
3358    //printf("REMOVE PART: %s\n", part);
3359 
3360    ep = rp->part;
3361    id = ep->id;
3362 
3363    /* Unlik Edje_Real_Parts that link to the removed one */
3364    for (i = 0; i < ed->table_parts_size; i++)
3365      {
3366         Edje_Real_Part *real;
3367 
3368         if (i == id) continue;  //don't check the deleted id
3369         real = ed->table_parts[i];
3370 
3371         if ((rp->type == EDJE_RP_TYPE_TEXT) &&
3372             (real->typedata.text) && (real->typedata.text->source == rp))
3373           real->typedata.text->source = NULL;
3374         if ((rp->type == EDJE_RP_TYPE_TEXT) &&
3375             (real->typedata.text) && (real->typedata.text->text_source == rp))
3376           real->typedata.text->text_source = NULL;
3377 
3378         if (real->part->clip_to_id == rp->part->id)
3379           {
3380              evas_object_clip_set(real->object, ed->base.clipper);
3381              real->part->clip_to_id = -1;
3382           }
3383         if (real->drag && real->drag->confine_to == rp)
3384           {
3385              real->drag->confine_to = NULL;
3386           }
3387         if (real->part->dragable.event_id != -1)
3388           {
3389              if (real->part->dragable.event_id == TO_INT(id))
3390                real->part->dragable.event_id = -1;
3391              else if (i > id)
3392                real->part->dragable.event_id--;
3393           }
3394 
3395         if (real->part->default_desc->map.id_persp == rp->part->id)
3396           real->part->default_desc->map.id_persp = -1;
3397         if (real->part->default_desc->map.id_light == rp->part->id)
3398           real->part->default_desc->map.id_light = -1;
3399         if (real->part->default_desc->map.rot.id_center == rp->part->id)
3400           real->part->default_desc->map.rot.id_center = -1;
3401 
3402         for (j = 0; j < real->part->other.desc_count; ++j)
3403           {
3404              if (real->part->other.desc[j]->map.id_persp == rp->part->id)
3405                real->part->other.desc[j]->map.id_persp = -1;
3406              if (real->part->other.desc[j]->map.id_light == rp->part->id)
3407                real->part->other.desc[j]->map.id_light = -1;
3408              if (real->part->other.desc[j]->map.rot.id_center == rp->part->id)
3409                real->part->other.desc[j]->map.rot.id_center = -1;
3410           }
3411      }
3412 
3413    /* Unlink all the parts and descriptions that refer to id */
3414    _edje_part_id_set(ed, rp, -1);
3415 
3416    /* Remove part from parts list */
3417    pc = ed->collection;
3418    pc->parts_count--;
3419    if (id < pc->parts_count) /* Forward parts */
3420      {
3421         int mcount = (pc->parts_count - id) * sizeof(Edje_Part *);
3422         memmove(&pc->parts[id], &pc->parts[id + 1], mcount);
3423      }
3424    pc->parts[pc->parts_count] = NULL;
3425    _edje_fix_parts_id(ed);
3426 
3427    /* Free Edje_Part and all descriptions */
3428    ce = eina_hash_find(ed->file->collection, ed->group);
3429 
3430    _edje_if_string_free(ed, &ep->name);
3431    if (ep->default_desc)
3432      {
3433         _edje_collection_free_part_description_free(ep->type, ep->default_desc, ce, 0);
3434         ep->default_desc = NULL;
3435      }
3436 
3437    for (k = 0; k < ep->other.desc_count; ++k)
3438      _edje_collection_free_part_description_free(ep->type, ep->other.desc[k], ce, 0);
3439 
3440    free(ep->other.desc);
3441    eina_mempool_free(ce->mp->mp.part, ep);
3442 
3443    /* Free Edje_Real_Part */
3444    _edje_real_part_free(ed, rp);
3445 
3446    /* if all parts are gone, hide the clipper */
3447    if (ed->table_parts_size == 0)
3448      evas_object_hide(ed->base.clipper);
3449 
3450    edje_object_calc_force(obj);
3451 
3452    ce->count.part--;
3453 
3454    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
3455 
3456    return EINA_TRUE;
3457 }
3458 
3459 static Eina_Bool
3460 _edje_edit_part_state_copy(Evas_Object *obj, const char *part_from, const char *part_to, const char *from, double val_from, const char *to, double val_to);
3461 
3462 EAPI Eina_Bool
edje_edit_part_copy(Evas_Object * obj,const char * part,const char * new_copy)3463 edje_edit_part_copy(Evas_Object *obj, const char *part, const char *new_copy)
3464 {
3465    Edje_Part *ep, *epcopy;
3466    unsigned int i, count;
3467    Edje_Real_Part *rpcopy;
3468 
3469    GET_RP_OR_RETURN(EINA_FALSE);
3470 
3471    ep = rp->part;
3472 
3473    /* Check if part doesn't exists */
3474    if (_edje_real_part_get(ed, new_copy))
3475      return EINA_FALSE;
3476 
3477    if (!ed->file) return EINA_FALSE;
3478 
3479    /* Create part (EXTERNAL or not) */
3480    if (!_edje_edit_real_part_add(obj, new_copy, ep->type, ep->source))
3481      return EINA_FALSE;
3482 
3483    /* Copy part's data */
3484    rpcopy = _edje_real_part_get(ed, new_copy);
3485    if (!rpcopy)
3486      return EINA_FALSE;
3487    epcopy = rpcopy->part;
3488 
3489 #define _PARAM_PART_COPY(param) \
3490   epcopy->param = ep->param;
3491 
3492    _PARAM_PART_COPY(scale)
3493    _PARAM_PART_COPY(mouse_events)
3494    _PARAM_PART_COPY(repeat_events)
3495    _PARAM_PART_COPY(ignore_flags)
3496    _PARAM_PART_COPY(mask_flags)
3497    _PARAM_PART_COPY(pointer_mode)
3498    _PARAM_PART_COPY(precise_is_inside)
3499    _PARAM_PART_COPY(use_alternate_font_metrics)
3500    _PARAM_PART_COPY(clip_to_id)
3501    _PARAM_PART_COPY(dragable.event_id)
3502    _PARAM_PART_COPY(dragable.confine_id)
3503    _PARAM_PART_COPY(dragable.threshold_id)
3504    _PARAM_PART_COPY(dragable.step_x)
3505    _PARAM_PART_COPY(dragable.step_y)
3506    _PARAM_PART_COPY(dragable.count_x)
3507    _PARAM_PART_COPY(dragable.count_y)
3508    _PARAM_PART_COPY(dragable.x)
3509    _PARAM_PART_COPY(dragable.y)
3510 
3511    if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
3512      {
3513         epcopy->source2 = (char *)eina_stringshare_add(ep->source2);
3514         epcopy->source3 = (char *)eina_stringshare_add(ep->source3);
3515         epcopy->source4 = (char *)eina_stringshare_add(ep->source4);
3516         epcopy->source5 = (char *)eina_stringshare_add(ep->source5);
3517         epcopy->source6 = (char *)eina_stringshare_add(ep->source6);
3518      }
3519 
3520 #ifdef HAVE_EPHYSICS
3521    _PARAM_PART_COPY(physics_body)
3522 #endif
3523 
3524    _PARAM_PART_COPY(effect)
3525    _PARAM_PART_COPY(entry_mode)
3526    _PARAM_PART_COPY(select_mode)
3527    _PARAM_PART_COPY(cursor_mode)
3528    _PARAM_PART_COPY(multiline)
3529    _PARAM_PART_COPY(access)
3530 
3531    if (ep->api.name)
3532      epcopy->api.name = eina_stringshare_add(ep->api.name);
3533    if (ep->api.description)
3534      epcopy->api.description = eina_stringshare_add(ep->api.description);
3535 
3536 #undef _PARAM_PART_COPY
3537 
3538    /* Copy default state */
3539    _edje_edit_part_state_copy(obj, part, new_copy, "default", 0.0, "default", 0.0);
3540 
3541    /* Copy all other states */
3542    count = rp->part->other.desc_count;
3543    for (i = 0; i < count; ++i)
3544      {
3545         _edje_edit_part_state_copy(obj, part, new_copy,
3546                                    rp->part->other.desc[i]->state.name, rp->part->other.desc[i]->state.value,
3547                                    rp->part->other.desc[i]->state.name, rp->part->other.desc[i]->state.value);
3548      }
3549 
3550    return EINA_TRUE;
3551 }
3552 
3553 EAPI Eina_Bool
edje_edit_part_exist(Evas_Object * obj,const char * part)3554 edje_edit_part_exist(Evas_Object *obj, const char *part)
3555 {
3556    GET_RP_OR_RETURN(EINA_FALSE);
3557    return EINA_TRUE;
3558 }
3559 
3560 EAPI const char *
edje_edit_part_below_get(Evas_Object * obj,const char * part)3561 edje_edit_part_below_get(Evas_Object *obj, const char *part)
3562 {
3563    Edje_Real_Part *prev;
3564 
3565    GET_RP_OR_RETURN(0);
3566 
3567    if (rp->part->id < 1) return NULL;
3568 
3569    prev = ed->table_parts[(rp->part->id - 1) % ed->table_parts_size];
3570 
3571    return eina_stringshare_add(prev->part->name);
3572 }
3573 
3574 EAPI const char *
edje_edit_part_above_get(Evas_Object * obj,const char * part)3575 edje_edit_part_above_get(Evas_Object *obj, const char *part)
3576 {
3577    Edje_Real_Part *next;
3578 
3579    GET_RP_OR_RETURN(0);
3580 
3581    if ((unsigned short)rp->part->id >= ed->table_parts_size - 1) return 0;
3582 
3583    next = ed->table_parts[(rp->part->id + 1) % ed->table_parts_size];
3584 
3585    return eina_stringshare_add(next->part->name);
3586 }
3587 
3588 EAPI Eina_Bool
edje_edit_part_restack_below(Evas_Object * obj,const char * part)3589 edje_edit_part_restack_below(Evas_Object *obj, const char *part)
3590 {
3591    Edje_Part_Collection *group;
3592    Edje_Real_Part *prev;
3593    Edje_Part *swap;
3594 
3595    GET_EED_OR_RETURN(EINA_FALSE);
3596    GET_RP_OR_RETURN(EINA_FALSE);
3597 
3598    //printf("RESTACK PART: %s BELOW\n", part);
3599 
3600    if (rp->part->id < 1) return EINA_FALSE;
3601    group = ed->collection;
3602 
3603    /* update parts list */
3604    prev = ed->table_parts[(rp->part->id - 1) % ed->table_parts_size];
3605 
3606    swap = group->parts[rp->part->id];
3607    group->parts[rp->part->id] = group->parts[prev->part->id];
3608    group->parts[prev->part->id] = swap;
3609 
3610    _edje_parts_id_switch(ed, rp, prev);
3611 
3612    evas_object_stack_below(rp->object, prev->object);
3613    if ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
3614        (rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object))
3615      evas_object_stack_above(rp->typedata.swallow->swallowed_object, rp->object);
3616 
3617    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
3618 
3619    return EINA_TRUE;
3620 }
3621 
3622 EAPI Eina_Bool
edje_edit_part_restack_part_below(Evas_Object * obj,const char * part,const char * below)3623 edje_edit_part_restack_part_below(Evas_Object *obj, const char *part, const char *below)
3624 {
3625    Edje_Part_Collection *group;
3626    Edje_Real_Part *rp, *rp_below, *prev;
3627    Edje_Part *swap;
3628 
3629    GET_EED_OR_RETURN(EINA_FALSE);
3630    GET_ED_OR_RETURN(EINA_FALSE);
3631    rp = _edje_real_part_get(ed, part);
3632    if (!rp) return EINA_FALSE;
3633    rp_below = _edje_real_part_get(ed, below);
3634    if (!rp_below) return EINA_FALSE;
3635 
3636    group = ed->collection;
3637 
3638    while (rp->part->id != (rp_below->part->id - 1))
3639      {
3640         if (rp->part->id > rp_below->part->id)
3641           prev = ed->table_parts[(rp->part->id - 1) % ed->table_parts_size];
3642         else
3643           prev = ed->table_parts[(rp->part->id + 1) % ed->table_parts_size];
3644         swap = group->parts[rp->part->id];
3645         group->parts[rp->part->id] = group->parts[prev->part->id];
3646         group->parts[prev->part->id] = swap;
3647         _edje_parts_id_switch(ed, rp, prev);
3648      }
3649 
3650    evas_object_stack_below(rp->object, rp_below->object);
3651    if ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
3652        (rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object))
3653      evas_object_stack_above(rp->typedata.swallow->swallowed_object, rp->object);
3654 
3655    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
3656 
3657    return EINA_TRUE;
3658 }
3659 
3660 EAPI Eina_Bool
edje_edit_part_restack_above(Evas_Object * obj,const char * part)3661 edje_edit_part_restack_above(Evas_Object *obj, const char *part)
3662 {
3663    Edje_Part_Collection *group;
3664    Edje_Real_Part *next;
3665    Edje_Part *swap;
3666 
3667    GET_EED_OR_RETURN(EINA_FALSE);
3668    GET_RP_OR_RETURN(EINA_FALSE);
3669 
3670    //printf("RESTACK PART: %s ABOVE\n", part);
3671 
3672    if ((unsigned short)rp->part->id >= ed->table_parts_size - 1) return EINA_FALSE;
3673 
3674    group = ed->collection;
3675 
3676    /* update parts list */
3677    next = ed->table_parts[(rp->part->id + 1) % ed->table_parts_size];
3678 
3679    swap = group->parts[rp->part->id];
3680    group->parts[rp->part->id] = group->parts[next->part->id];
3681    group->parts[next->part->id] = swap;
3682 
3683    /* update ids */
3684    _edje_parts_id_switch(ed, rp, next);
3685 
3686    evas_object_stack_above(rp->object, next->object);
3687    if ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
3688        (rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object))
3689      evas_object_stack_above(rp->typedata.swallow->swallowed_object, rp->object);
3690 
3691    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
3692 
3693    return EINA_TRUE;
3694 }
3695 
3696 EAPI Eina_Bool
edje_edit_part_restack_part_above(Evas_Object * obj,const char * part,const char * above)3697 edje_edit_part_restack_part_above(Evas_Object *obj, const char *part, const char *above)
3698 {
3699    Edje_Part_Collection *group;
3700    Edje_Real_Part *rp, *rp_above, *next;
3701    Edje_Part *swap;
3702 
3703    GET_EED_OR_RETURN(EINA_FALSE);
3704    GET_ED_OR_RETURN(EINA_FALSE);
3705    rp = _edje_real_part_get(ed, part);
3706    if (!rp) return EINA_FALSE;
3707    rp_above = _edje_real_part_get(ed, above);
3708    if (!rp_above) return EINA_FALSE;
3709 
3710    group = ed->collection;
3711 
3712    while (rp->part->id != rp_above->part->id + 1)
3713      {
3714         if (rp->part->id > rp_above->part->id)
3715           next = ed->table_parts[(rp->part->id - 1) % ed->table_parts_size];
3716         else
3717           next = ed->table_parts[(rp->part->id + 1) % ed->table_parts_size];
3718         swap = group->parts[rp->part->id];
3719         group->parts[rp->part->id] = group->parts[next->part->id];
3720         group->parts[next->part->id] = swap;
3721         _edje_parts_id_switch(ed, rp, next);
3722      }
3723 
3724    evas_object_stack_above(rp->object, rp_above->object);
3725    if ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
3726        (rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object))
3727      evas_object_stack_above(rp->typedata.swallow->swallowed_object, rp->object);
3728 
3729    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
3730 
3731    return EINA_TRUE;
3732 }
3733 
3734 EAPI Edje_Part_Type
edje_edit_part_type_get(Evas_Object * obj,const char * part)3735 edje_edit_part_type_get(Evas_Object *obj, const char *part)
3736 {
3737    GET_RP_OR_RETURN(0);
3738    return rp->part->type;
3739 }
3740 
3741 EAPI const char *
edje_edit_part_selected_state_get(Evas_Object * obj,const char * part,double * value)3742 edje_edit_part_selected_state_get(Evas_Object *obj, const char *part, double *value)
3743 {
3744    GET_RP_OR_RETURN(NULL);
3745 
3746    if (!rp->chosen_description)
3747      {
3748         if (value) *value = 0.0;  // FIXME: Make sure edje_edit supports correctly the default having any value
3749         return eina_stringshare_add("default");
3750      }
3751 
3752    if (value) *value = rp->chosen_description->state.value;
3753    return eina_stringshare_add(rp->chosen_description->state.name);
3754 }
3755 
3756 EAPI Eina_Bool
edje_edit_part_selected_state_set(Evas_Object * obj,const char * part,const char * state,double value)3757 edje_edit_part_selected_state_set(Evas_Object *obj, const char *part, const char *state, double value)
3758 {
3759    Edje_Part_Description_Common *pd;
3760 
3761    GET_EED_OR_RETURN(EINA_FALSE);
3762    GET_RP_OR_RETURN(EINA_FALSE);
3763 
3764    pd = _edje_part_description_find_byname(eed, part, state, value);
3765    if (!pd) return EINA_FALSE;
3766 
3767    //printf("EDJE: Set state: %s %f\n", pd->state.name, pd->state.value);
3768    _edje_part_description_apply(ed, rp, pd->state.name, pd->state.value, NULL, 0.0);
3769 
3770    edje_object_calc_force(obj);
3771    return EINA_TRUE;
3772 }
3773 
3774 static const char *
_edje_part_clip_to_get(Edje * ed,Edje_Real_Part * rp)3775 _edje_part_clip_to_get(Edje *ed, Edje_Real_Part *rp)
3776 {
3777    Edje_Real_Part *clip = NULL;
3778 
3779    if (rp->part->clip_to_id < 0) return NULL;
3780 
3781    clip = ed->table_parts[rp->part->clip_to_id % ed->table_parts_size];
3782    if (!clip || !clip->part || !clip->part->name) return NULL;
3783 
3784    return eina_stringshare_add(clip->part->name);
3785 }
3786 
3787 EAPI const char *
edje_edit_part_clip_to_get(Evas_Object * obj,const char * part)3788 edje_edit_part_clip_to_get(Evas_Object *obj, const char *part)
3789 {
3790    GET_RP_OR_RETURN(NULL);
3791 
3792    return _edje_part_clip_to_get(ed, rp);
3793 }
3794 
3795 EAPI Eina_Bool
edje_edit_part_clip_to_set(Evas_Object * obj,const char * part,const char * clip_to)3796 edje_edit_part_clip_to_set(Evas_Object *obj, const char *part, const char *clip_to)
3797 {
3798    Edje_Real_Part *clip;
3799    Evas_Object *o, *oo;
3800 
3801    GET_RP_OR_RETURN(EINA_FALSE);
3802 
3803    /* unset clipping */
3804    if (!clip_to)
3805      {
3806         evas_object_clip_set(rp->object, ed->base.clipper);
3807         if ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
3808             (rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object))
3809           evas_object_clip_set(rp->typedata.swallow->swallowed_object, ed->base.clipper);
3810 
3811         rp->part->clip_to_id = -1;
3812 
3813         edje_object_calc_force(obj);
3814 
3815         return EINA_TRUE;
3816      }
3817 
3818    /* set clipping */
3819    //printf("Set clip_to for part: %s [to: %s]\n", part, clip_to);
3820    clip = _edje_real_part_get(ed, clip_to);
3821    if (!clip || !clip->part) return EINA_FALSE;
3822    o = clip->object;
3823    while ((oo = evas_object_clip_get(o)))
3824      {
3825         if (o == rp->object)
3826           return EINA_FALSE;
3827         o = oo;
3828      }
3829 
3830    rp->part->clip_to_id = clip->part->id;
3831 
3832    if ((rp->type == EDJE_RP_TYPE_SWALLOW) &&
3833        (rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object))
3834      evas_object_clip_set(rp->typedata.swallow->swallowed_object, clip->object);
3835 
3836    edje_object_calc_force(obj);
3837 
3838    return EINA_TRUE;
3839 }
3840 
3841 EAPI Eina_Bool
edje_edit_part_mouse_events_get(Evas_Object * obj,const char * part)3842 edje_edit_part_mouse_events_get(Evas_Object *obj, const char *part)
3843 {
3844    GET_RP_OR_RETURN(EINA_FALSE);
3845    return rp->part->mouse_events;
3846 }
3847 
3848 EAPI Eina_Bool
edje_edit_part_mouse_events_set(Evas_Object * obj,const char * part,Eina_Bool mouse_events)3849 edje_edit_part_mouse_events_set(Evas_Object *obj, const char *part, Eina_Bool mouse_events)
3850 {
3851    GET_RP_OR_RETURN(EINA_FALSE);
3852 
3853    if (!rp->object) return EINA_FALSE;
3854 
3855    rp->part->mouse_events = mouse_events ? 1 : 0;
3856 
3857    if (mouse_events)
3858      {
3859         evas_object_pass_events_set(rp->object, 0);
3860         _edje_callbacks_add(rp->object, ed, rp);
3861      }
3862    else
3863      {
3864         evas_object_pass_events_set(rp->object, 1);
3865         _edje_callbacks_del(rp->object, ed);
3866      }
3867    return EINA_TRUE;
3868 }
3869 
3870 EAPI Eina_Bool
edje_edit_part_required_get(Evas_Object * obj,const char * part)3871 edje_edit_part_required_get(Evas_Object *obj, const char *part)
3872 {
3873    GET_RP_OR_RETURN(EINA_FALSE);
3874    return rp->part->required;
3875 }
3876 
3877 EAPI Eina_Bool
edje_edit_part_anti_alias_get(Evas_Object * obj,const char * part)3878 edje_edit_part_anti_alias_get(Evas_Object *obj, const char *part)
3879 {
3880    GET_RP_OR_RETURN(EINA_FALSE);
3881    return rp->part->anti_alias;
3882 }
3883 
3884 EAPI Eina_Bool
edje_edit_part_anti_alias_set(Evas_Object * obj,const char * part,Eina_Bool anti_alias)3885 edje_edit_part_anti_alias_set(Evas_Object *obj, const char *part, Eina_Bool anti_alias)
3886 {
3887    GET_RP_OR_RETURN(EINA_FALSE);
3888 
3889    if (!rp->object) return EINA_FALSE;
3890 
3891    rp->part->anti_alias = anti_alias ? 1 : 0;
3892    evas_object_anti_alias_set(obj, rp->part->anti_alias);
3893 
3894    return EINA_TRUE;
3895 }
3896 
3897 EAPI Eina_Bool
edje_edit_part_repeat_events_get(Evas_Object * obj,const char * part)3898 edje_edit_part_repeat_events_get(Evas_Object *obj, const char *part)
3899 {
3900    GET_RP_OR_RETURN(EINA_FALSE);
3901    return rp->part->repeat_events;
3902 }
3903 
3904 EAPI Eina_Bool
edje_edit_part_repeat_events_set(Evas_Object * obj,const char * part,Eina_Bool repeat_events)3905 edje_edit_part_repeat_events_set(Evas_Object *obj, const char *part, Eina_Bool repeat_events)
3906 {
3907    GET_RP_OR_RETURN(EINA_FALSE);
3908 
3909    if (!rp->object) return EINA_FALSE;
3910 
3911    rp->part->repeat_events = repeat_events ? 1 : 0;
3912 
3913    if (repeat_events)
3914      evas_object_repeat_events_set(rp->object, 1);
3915    else
3916      evas_object_repeat_events_set(rp->object, 0);
3917 
3918    return EINA_TRUE;
3919 }
3920 
3921 EAPI Eina_Bool
edje_edit_part_use_alternate_font_metrics_get(Evas_Object * obj,const char * part)3922 edje_edit_part_use_alternate_font_metrics_get(Evas_Object *obj, const char *part)
3923 {
3924    GET_RP_OR_RETURN(0);
3925 
3926    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
3927        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
3928      return EINA_FALSE;
3929 
3930    return rp->part->use_alternate_font_metrics;
3931 }
3932 
3933 EAPI Eina_Bool
edje_edit_part_use_alternate_font_metrics_set(Evas_Object * obj,const char * part,Eina_Bool use)3934 edje_edit_part_use_alternate_font_metrics_set(Evas_Object *obj, const char *part, Eina_Bool use)
3935 {
3936    GET_RP_OR_RETURN(EINA_FALSE);
3937 
3938    if ((!rp->object) ||
3939        ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
3940         (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)))
3941      return EINA_FALSE;
3942 
3943    rp->part->use_alternate_font_metrics = use;
3944    return EINA_TRUE;
3945 }
3946 
3947 EAPI Eina_Bool
edje_edit_part_multiline_get(Evas_Object * obj,const char * part)3948 edje_edit_part_multiline_get(Evas_Object *obj, const char *part)
3949 {
3950    GET_RP_OR_RETURN(0);
3951 
3952    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
3953        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
3954      return EINA_FALSE;
3955 
3956    return rp->part->multiline;
3957 }
3958 
3959 EAPI Eina_Bool
edje_edit_part_multiline_set(Evas_Object * obj,const char * part,Eina_Bool multiline)3960 edje_edit_part_multiline_set(Evas_Object *obj, const char *part, Eina_Bool multiline)
3961 {
3962    GET_RP_OR_RETURN(EINA_FALSE);
3963 
3964    if ((!rp->object) ||
3965        ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
3966         (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)))
3967      return EINA_FALSE;
3968 
3969    rp->part->multiline = multiline;
3970    return EINA_TRUE;
3971 }
3972 
3973 EAPI Eina_Bool
edje_edit_part_precise_is_inside_get(Evas_Object * obj,const char * part)3974 edje_edit_part_precise_is_inside_get(Evas_Object *obj, const char *part)
3975 {
3976    GET_RP_OR_RETURN(0);
3977 
3978    return rp->part->precise_is_inside;
3979 }
3980 
3981 EAPI Eina_Bool
edje_edit_part_precise_is_inside_set(Evas_Object * obj,const char * part,Eina_Bool precise_is_inside)3982 edje_edit_part_precise_is_inside_set(Evas_Object *obj, const char *part, Eina_Bool precise_is_inside)
3983 {
3984    GET_RP_OR_RETURN(EINA_FALSE);
3985 
3986    if (!rp->object) return EINA_FALSE;
3987 
3988    rp->part->precise_is_inside = precise_is_inside;
3989    return EINA_TRUE;
3990 }
3991 
3992 EAPI Eina_Bool
edje_edit_part_access_get(Evas_Object * obj,const char * part)3993 edje_edit_part_access_get(Evas_Object *obj, const char *part)
3994 {
3995    GET_RP_OR_RETURN(0);
3996 
3997    return rp->part->access;
3998 }
3999 
4000 EAPI Eina_Bool
edje_edit_part_access_set(Evas_Object * obj,const char * part,Eina_Bool access_mode)4001 edje_edit_part_access_set(Evas_Object *obj, const char *part, Eina_Bool access_mode)
4002 {
4003    GET_RP_OR_RETURN(EINA_FALSE);
4004 
4005    if (!rp->object) return EINA_FALSE;
4006 
4007    rp->part->access = access_mode;
4008    return EINA_TRUE;
4009 }
4010 
4011 EAPI Evas_Event_Flags
edje_edit_part_ignore_flags_get(Evas_Object * obj,const char * part)4012 edje_edit_part_ignore_flags_get(Evas_Object *obj, const char *part)
4013 {
4014    GET_RP_OR_RETURN(0);
4015 
4016    return rp->part->ignore_flags;
4017 }
4018 
4019 EAPI Eina_Bool
edje_edit_part_ignore_flags_set(Evas_Object * obj,const char * part,Evas_Event_Flags ignore_flags)4020 edje_edit_part_ignore_flags_set(Evas_Object *obj, const char *part, Evas_Event_Flags ignore_flags)
4021 {
4022    GET_RP_OR_RETURN(EINA_FALSE);
4023 
4024    if (!rp->object) return EINA_FALSE;
4025 
4026    rp->part->ignore_flags = ignore_flags;
4027    return EINA_TRUE;
4028 }
4029 
4030 EAPI Evas_Event_Flags
edje_edit_part_mask_flags_get(Evas_Object * obj,const char * part)4031 edje_edit_part_mask_flags_get(Evas_Object *obj, const char *part)
4032 {
4033    GET_RP_OR_RETURN(0);
4034 
4035    return rp->part->mask_flags;
4036 }
4037 
4038 EAPI Eina_Bool
edje_edit_part_mask_flags_set(Evas_Object * obj,const char * part,Evas_Event_Flags mask_flags)4039 edje_edit_part_mask_flags_set(Evas_Object *obj, const char *part, Evas_Event_Flags mask_flags)
4040 {
4041    GET_RP_OR_RETURN(EINA_FALSE);
4042 
4043    if (!rp->object) return EINA_FALSE;
4044 
4045    rp->part->mask_flags = mask_flags;
4046    return EINA_TRUE;
4047 }
4048 
4049 EAPI Evas_Object_Pointer_Mode
edje_edit_part_pointer_mode_get(Evas_Object * obj,const char * part)4050 edje_edit_part_pointer_mode_get(Evas_Object *obj, const char *part)
4051 {
4052    GET_RP_OR_RETURN(0);
4053 
4054    return rp->part->pointer_mode;
4055 }
4056 
4057 EAPI Eina_Bool
edje_edit_part_pointer_mode_set(Evas_Object * obj,const char * part,Evas_Object_Pointer_Mode pointer_mode)4058 edje_edit_part_pointer_mode_set(Evas_Object *obj, const char *part, Evas_Object_Pointer_Mode pointer_mode)
4059 {
4060    GET_RP_OR_RETURN(EINA_FALSE);
4061 
4062    if (!rp->object) return EINA_FALSE;
4063 
4064    rp->part->pointer_mode = pointer_mode;
4065    return EINA_TRUE;
4066 }
4067 
4068 EAPI unsigned char
edje_edit_part_cursor_mode_get(Evas_Object * obj,const char * part)4069 edje_edit_part_cursor_mode_get(Evas_Object *obj, const char *part)
4070 {
4071    GET_RP_OR_RETURN(0);
4072 
4073    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
4074        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
4075      return 0;
4076 
4077    return rp->part->cursor_mode;
4078 }
4079 
4080 EAPI Eina_Bool
edje_edit_part_cursor_mode_set(Evas_Object * obj,const char * part,unsigned char cursor_mode)4081 edje_edit_part_cursor_mode_set(Evas_Object *obj, const char *part, unsigned char cursor_mode)
4082 {
4083    GET_RP_OR_RETURN(EINA_FALSE);
4084 
4085    if ((!rp->object) ||
4086        ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
4087         (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)))
4088      return EINA_FALSE;
4089 
4090    rp->part->cursor_mode = cursor_mode;
4091    return EINA_TRUE;
4092 }
4093 
4094 EAPI Eina_Bool
edje_edit_part_scale_set(Evas_Object * obj,const char * part,Eina_Bool scale)4095 edje_edit_part_scale_set(Evas_Object *obj, const char *part, Eina_Bool scale)
4096 {
4097    GET_RP_OR_RETURN(EINA_FALSE);
4098 
4099    rp->part->scale = scale ? 1 : 0;
4100    edje_object_calc_force(obj);
4101    return EINA_TRUE;
4102 }
4103 
4104 EAPI Eina_Bool
edje_edit_part_scale_get(Evas_Object * obj,const char * part)4105 edje_edit_part_scale_get(Evas_Object *obj, const char *part)
4106 {
4107    GET_RP_OR_RETURN(EINA_FALSE);
4108 
4109    return rp->part->scale;
4110 }
4111 
4112 EAPI const char *
edje_edit_part_source_get(Evas_Object * obj,const char * part)4113 edje_edit_part_source_get(Evas_Object *obj, const char *part)
4114 {
4115    GET_RP_OR_RETURN(NULL);
4116 
4117    //printf("Get source for part: %s\n", part);
4118    if (!rp->part->source) return NULL;
4119 
4120    return eina_stringshare_add(rp->part->source);
4121 }
4122 
4123 static Eina_Bool
_check_recursive_reference(Edje * ed,const char * source,Eina_List * group_path,Edje_Part * part)4124 _check_recursive_reference(Edje *ed, const char *source, Eina_List *group_path, Edje_Part *part)
4125 {
4126    char *data;
4127    Edje_Part_Collection_Directory_Entry *pce;
4128    Eina_List *l, *part_list, *pll;
4129    Eina_Bool no_ref = EINA_TRUE;
4130    Eina_Stringshare *part_name, *part_source = NULL;
4131    Edje_Part_Type type;
4132 
4133    if (!source) return EINA_TRUE;
4134 
4135    pce = eina_hash_find(ed->file->collection, source);
4136 
4137    /* forcing collection load into memory */
4138    Evas_Object *part_obj = edje_edit_object_add(ed->base.evas);
4139    edje_object_file_set(part_obj, ed->file->path, pce->entry);
4140    /* Go through every part to find parts with type GROUP */
4141    part_list = edje_edit_parts_list_get(part_obj);
4142    EINA_LIST_FOREACH(part_list, pll, part_name)
4143      {
4144         eina_stringshare_del(part_source);
4145         part_source = edje_edit_part_source_get(part_obj, part_name);
4146         type = edje_edit_part_type_get(part_obj, part_name);
4147         if ((type == EDJE_PART_TYPE_GROUP) && part_source)
4148           {
4149              /* Make sure that this group isn't already in the tree of parents */
4150              EINA_LIST_FOREACH(group_path, l, data)
4151                {
4152                   if (data == part_source)
4153                     {
4154                        no_ref = EINA_FALSE;
4155                        goto end;
4156                     }
4157                }
4158              group_path = eina_list_append(group_path, source);
4159              no_ref &= _check_recursive_reference(ed, part_source, group_path, part);
4160           }
4161 
4162         /* We did a loop here... this part doesn't have source yet,
4163            but if it will set, it'll be a recursive reference. */
4164         if (!strcmp(part_name, part->name)) /* TODO: check if part->name is also stringshare and values can be compared with == */
4165           {
4166              no_ref = EINA_FALSE;
4167              goto end;
4168           }
4169      }
4170 end:
4171    eina_stringshare_del(part_source);
4172    edje_edit_string_list_free(part_list);
4173    evas_object_del(part_obj);
4174    return no_ref;
4175 }
4176 
4177 EAPI Eina_Bool
edje_edit_part_source_set(Evas_Object * obj,const char * part,const char * source)4178 edje_edit_part_source_set(Evas_Object *obj, const char *part, const char *source)
4179 {
4180    GET_RP_OR_RETURN(EINA_FALSE);
4181 
4182    Evas_Object *child_obj;
4183    Eina_List *group_path = NULL;
4184    //printf("Set source for part: %s [source: %s]\n", part, source);
4185 
4186    switch (rp->part->type)
4187      {
4188       case EDJE_PART_TYPE_GROUP:
4189         /* find source group */
4190         if (!_check_recursive_reference(ed, source, group_path, rp->part))
4191           return EINA_FALSE;
4192 
4193         if ((rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object))
4194           {
4195              evas_object_del(rp->typedata.swallow->swallowed_object);
4196              _edje_real_part_swallow_clear(ed, rp);
4197           }
4198         if (source)
4199           {
4200              child_obj = edje_object_add(ed->base.evas);
4201              edje_object_file_set(child_obj, ed->file->path, source);
4202              _edje_real_part_swallow(ed, rp, child_obj, EINA_TRUE);
4203           }
4204         EINA_FALLTHROUGH;
4205 
4206       // this fall through case is intentional
4207       case EDJE_PART_TYPE_TEXTBLOCK:
4208         if (source) _edje_if_string_replace(ed, &rp->part->source, source);
4209         else _edje_if_string_free(ed, &rp->part->source);
4210         return EINA_TRUE;
4211 
4212       case EDJE_PART_TYPE_EXTERNAL: //EXTERNAL part has source property but it cannot be changed
4213         break;
4214 
4215       default:
4216         break;
4217      }
4218    return EINA_FALSE;
4219 }
4220 
4221 #define TEXT_BLOCK_SOURCE_GET(N)                                          \
4222   EAPI const char *                                                       \
4223   edje_edit_part_source ## N ## _get(Evas_Object * obj, const char *part) \
4224   {                                                                       \
4225      GET_RP_OR_RETURN(NULL);                                              \
4226      if (!rp->part->source ## N) return NULL;                             \
4227      return eina_stringshare_add(rp->part->source ## N);                  \
4228   }
4229 
4230 #define TEXT_BLOCK_SOURCE_SET(N)                                                             \
4231   EAPI Eina_Bool                                                                             \
4232   edje_edit_part_source ## N ##_set(Evas_Object * obj, const char *part, const char *source) \
4233   {                                                                                          \
4234      GET_RP_OR_RETURN(EINA_FALSE);                                                           \
4235                                                                                              \
4236      if (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)                                         \
4237        return EINA_FALSE;                                                                    \
4238                                                                                              \
4239      eina_stringshare_del(rp->part->source ## N);                                            \
4240      if (source)                                                                             \
4241        rp->part->source ## N = eina_stringshare_add(source);                                 \
4242      else                                                                                    \
4243        rp->part->source ## N = NULL;                                                         \
4244      edje_object_calc_force(obj);                                                            \
4245      return EINA_TRUE;                                                                       \
4246   }
4247 TEXT_BLOCK_SOURCE_GET(2);
4248 TEXT_BLOCK_SOURCE_GET(3);
4249 TEXT_BLOCK_SOURCE_GET(4);
4250 TEXT_BLOCK_SOURCE_GET(5);
4251 TEXT_BLOCK_SOURCE_GET(6);
4252 
4253 TEXT_BLOCK_SOURCE_SET(2);
4254 TEXT_BLOCK_SOURCE_SET(3);
4255 TEXT_BLOCK_SOURCE_SET(4);
4256 TEXT_BLOCK_SOURCE_SET(5);
4257 TEXT_BLOCK_SOURCE_SET(6);
4258 
4259 EAPI int
edje_edit_part_drag_x_get(Evas_Object * obj,const char * part)4260 edje_edit_part_drag_x_get(Evas_Object *obj, const char *part)
4261 {
4262    GET_RP_OR_RETURN(0);
4263    return rp->part->dragable.x;
4264 }
4265 
4266 EAPI Eina_Bool
edje_edit_part_drag_x_set(Evas_Object * obj,const char * part,int drag)4267 edje_edit_part_drag_x_set(Evas_Object *obj, const char *part, int drag)
4268 {
4269    GET_RP_OR_RETURN(EINA_FALSE);
4270    rp->part->dragable.x = drag;
4271 
4272    if (!drag && !rp->part->dragable.y)
4273      {
4274         free(rp->drag);
4275         rp->drag = NULL;
4276         return EINA_TRUE;
4277      }
4278 
4279    if (rp->drag) return EINA_TRUE;
4280 
4281    rp->drag = _alloc(sizeof (Edje_Real_Part_Drag));
4282    if (!rp->drag) return EINA_FALSE;
4283 
4284    rp->drag->step.x = rp->part->dragable.step_x;
4285    rp->drag->step.y = rp->part->dragable.step_y;
4286    return EINA_TRUE;
4287 }
4288 
4289 EAPI int
edje_edit_part_drag_y_get(Evas_Object * obj,const char * part)4290 edje_edit_part_drag_y_get(Evas_Object *obj, const char *part)
4291 {
4292    GET_RP_OR_RETURN(0);
4293    return rp->part->dragable.y;
4294 }
4295 
4296 EAPI Eina_Bool
edje_edit_part_drag_y_set(Evas_Object * obj,const char * part,int drag)4297 edje_edit_part_drag_y_set(Evas_Object *obj, const char *part, int drag)
4298 {
4299    GET_RP_OR_RETURN(EINA_FALSE);
4300    rp->part->dragable.y = drag;
4301 
4302    if (!drag && !rp->part->dragable.x)
4303      {
4304         free(rp->drag);
4305         rp->drag = NULL;
4306         return EINA_TRUE;
4307      }
4308 
4309    if (rp->drag) return EINA_TRUE;
4310 
4311    rp->drag = _alloc(sizeof (Edje_Real_Part_Drag));
4312    if (!rp->drag) return EINA_FALSE;
4313 
4314    rp->drag->step.x = rp->part->dragable.step_x;
4315    rp->drag->step.y = rp->part->dragable.step_y;
4316    return EINA_TRUE;
4317 }
4318 
4319 #define FUNC_PART_DRAG_INT(Class, Value)                                                  \
4320   EAPI int                                                                                \
4321   edje_edit_part_drag_##Class##_##Value##_get(Evas_Object * obj, const char *part)        \
4322   {                                                                                       \
4323      GET_RP_OR_RETURN(0);                                                                 \
4324      return rp->part->dragable.Class##_##Value;                                           \
4325   }                                                                                       \
4326   EAPI Eina_Bool                                                                          \
4327   edje_edit_part_drag_##Class##_##Value##_set(Evas_Object * obj, const char *part, int v) \
4328   {                                                                                       \
4329      GET_RP_OR_RETURN(EINA_FALSE);                                                        \
4330      rp->part->dragable.Class##_##Value = v;                                              \
4331      return EINA_TRUE;                                                                    \
4332   }
4333 
4334 FUNC_PART_DRAG_INT(step, x);
4335 FUNC_PART_DRAG_INT(step, y);
4336 FUNC_PART_DRAG_INT(count, x);
4337 FUNC_PART_DRAG_INT(count, y);
4338 
4339 #define FUNC_PART_DRAG_ID(Id)                                                        \
4340   EAPI const char *                                                                  \
4341   edje_edit_part_drag_##Id##_get(Evas_Object * obj, const char *part)                \
4342   {                                                                                  \
4343      Edje_Real_Part *p;                                                              \
4344                                                                                      \
4345      GET_RP_OR_RETURN(NULL);                                                         \
4346                                                                                      \
4347      if (rp->part->dragable.Id##_id < 0)                                             \
4348        return NULL;                                                                  \
4349                                                                                      \
4350      p = ed->table_parts[rp->part->dragable.Id##_id];                                \
4351      return eina_stringshare_add(p->part->name);                                     \
4352   }                                                                                  \
4353   EAPI Eina_Bool                                                                     \
4354   edje_edit_part_drag_##Id##_set(Evas_Object * obj, const char *part, const char *e) \
4355   {                                                                                  \
4356      Edje_Real_Part *e_part;                                                         \
4357                                                                                      \
4358      eina_error_set(0);                                                              \
4359      if ((!obj) || (!part))                                                          \
4360        return EINA_FALSE;                                                            \
4361                                                                                      \
4362      GET_RP_OR_RETURN(EINA_FALSE);                                                   \
4363      if (!e)                                                                         \
4364        {                                                                             \
4365           rp->part->dragable.Id##_id = -1;                                           \
4366           return EINA_TRUE;                                                          \
4367        }                                                                             \
4368      e_part = _edje_real_part_get(ed, e);                                            \
4369      if (!e_part) return EINA_FALSE;                                                 \
4370      rp->part->dragable.Id##_id = e_part->part->id;                                  \
4371      return EINA_TRUE;                                                               \
4372   }
4373 
4374 FUNC_PART_DRAG_ID(confine);
4375 FUNC_PART_DRAG_ID(event);
4376 FUNC_PART_DRAG_ID(threshold);
4377 
4378 /***************************/
4379 /*         BOX API         */
4380 /***************************/
4381 
4382 #define FUNC_STATE_BOX_LAYOUT(Layout)                                                                                    \
4383   EAPI Eina_Stringshare *                                                                                                \
4384   edje_edit_state_box_##Layout##_get(Evas_Object * obj, const char *part, const char *state, double value)               \
4385   {                                                                                                                      \
4386      GET_PD_OR_RETURN(0)                                                                                                 \
4387      if (rp->part->type == EDJE_PART_TYPE_BOX)                                                                           \
4388        {                                                                                                                 \
4389           Edje_Part_Description_Box *box;                                                                                \
4390           box = (Edje_Part_Description_Box *)pd;                                                                         \
4391           return eina_stringshare_add(box->box.Layout);                                                                  \
4392        }                                                                                                                 \
4393      return NULL;                                                                                                        \
4394   }                                                                                                                      \
4395   EAPI Eina_Bool                                                                                                         \
4396   edje_edit_state_box_##Layout##_set(Evas_Object * obj, const char *part, const char *state, double value, char *layout) \
4397   {                                                                                                                      \
4398      GET_PD_OR_RETURN(EINA_FALSE)                                                                                        \
4399      if (rp->part->type == EDJE_PART_TYPE_BOX)                                                                           \
4400        {                                                                                                                 \
4401           Edje_Part_Description_Box *box;                                                                                \
4402           box = (Edje_Part_Description_Box *)pd;                                                                         \
4403           box->box.Layout = layout;                                                                                      \
4404        }                                                                                                                 \
4405      else                                                                                                                \
4406        return EINA_FALSE;                                                                                                \
4407      return EINA_TRUE;                                                                                                   \
4408   }
4409 
4410 FUNC_STATE_BOX_LAYOUT(layout);
4411 FUNC_STATE_BOX_LAYOUT(alt_layout);
4412 
4413 /***************************/
4414 /*        TABLE API        */
4415 /***************************/
4416 
4417 EAPI unsigned char
edje_edit_state_table_homogeneous_get(Evas_Object * obj,const char * part,const char * state,double value)4418 edje_edit_state_table_homogeneous_get(Evas_Object *obj, const char *part, const char *state, double value)
4419 {
4420    GET_PD_OR_RETURN(0)
4421 
4422    switch (rp->part->type)
4423      {
4424       case EDJE_PART_TYPE_TABLE:
4425       {
4426          Edje_Part_Description_Table *table;
4427          table = (Edje_Part_Description_Table *)pd;
4428          return table->table.homogeneous;
4429       }
4430 
4431       default:
4432         return 0;
4433      }
4434    return 0;
4435 }
4436 
4437 EAPI Eina_Bool
edje_edit_state_table_homogeneous_set(Evas_Object * obj,const char * part,const char * state,double value,unsigned char homogeneous)4438 edje_edit_state_table_homogeneous_set(Evas_Object *obj, const char *part, const char *state, double value, unsigned char homogeneous)
4439 {
4440    GET_PD_OR_RETURN(EINA_FALSE)
4441 
4442    switch (rp->part->type)
4443      {
4444       case EDJE_PART_TYPE_TABLE:
4445       {
4446          Edje_Part_Description_Table *table;
4447          table = (Edje_Part_Description_Table *)pd;
4448          table->table.homogeneous = homogeneous;
4449          break;
4450       }
4451 
4452       default:
4453         return EINA_FALSE;
4454      }
4455    return EINA_TRUE;
4456 }
4457 
4458 /***************************/
4459 /*     BOX & TABLE API     */
4460 /***************************/
4461 
4462 #define FUNC_CONTAINER_BOOL(CLASS, VALUE) \
4463 EAPI Eina_Bool \
4464 edje_edit_state_container_##CLASS##_##VALUE##_get(Evas_Object *obj, const char *part, const char *state, double value) \
4465 { \
4466    Eina_Bool val; \
4467    GET_PD_OR_RETURN(EINA_FALSE) \
4468    switch (rp->part->type) \
4469      { \
4470       case EDJE_PART_TYPE_TABLE: \
4471       { \
4472          Edje_Part_Description_Table *table; \
4473          table = (Edje_Part_Description_Table *)pd; \
4474          val = table->table.CLASS.VALUE; \
4475          break; \
4476       } \
4477       case EDJE_PART_TYPE_BOX: \
4478       { \
4479          Edje_Part_Description_Box *box; \
4480          box = (Edje_Part_Description_Box *)pd; \
4481          val = box->box.CLASS.VALUE; \
4482          break; \
4483       } \
4484       default: \
4485        val = EINA_FALSE; \
4486      } \
4487    return val; \
4488 } \
4489 EAPI Eina_Bool \
4490 edje_edit_state_container_##CLASS##_##VALUE##_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool new_val) \
4491 { \
4492    GET_PD_OR_RETURN(EINA_FALSE) \
4493    switch (rp->part->type) \
4494      { \
4495       case EDJE_PART_TYPE_TABLE: \
4496       { \
4497          Edje_Part_Description_Table *table; \
4498          table = (Edje_Part_Description_Table *)pd; \
4499          table->table.CLASS.VALUE = new_val; \
4500          break; \
4501       } \
4502       case EDJE_PART_TYPE_BOX: \
4503       { \
4504          Edje_Part_Description_Box *box; \
4505          box = (Edje_Part_Description_Box *)pd; \
4506          box->box.CLASS.VALUE = new_val; \
4507          break; \
4508       } \
4509       default: \
4510         return EINA_FALSE; \
4511      } \
4512    return EINA_TRUE; \
4513 }
4514 
FUNC_CONTAINER_BOOL(min,v)4515 FUNC_CONTAINER_BOOL(min, v)
4516 FUNC_CONTAINER_BOOL(min, h)
4517 
4518 #undef FUNC_CONTAINER_BOOL
4519 
4520 #define FUNC_CONTAINER_INT(CLASS, VALUE) \
4521 EAPI int \
4522 edje_edit_state_container_##CLASS##_##VALUE##_get(Evas_Object *obj, const char *part, const char *state, double value) \
4523 { \
4524    int val; \
4525    GET_PD_OR_RETURN(EINA_FALSE) \
4526    switch (rp->part->type) \
4527      { \
4528       case EDJE_PART_TYPE_TABLE: \
4529       { \
4530          Edje_Part_Description_Table *table; \
4531          table = (Edje_Part_Description_Table *)pd; \
4532          val = table->table.CLASS.VALUE; \
4533          break; \
4534       } \
4535       case EDJE_PART_TYPE_BOX: \
4536       { \
4537          Edje_Part_Description_Box *box; \
4538          box = (Edje_Part_Description_Box *)pd; \
4539          val = box->box.CLASS.VALUE; \
4540          break; \
4541       } \
4542       default: \
4543         val = 0; \
4544      } \
4545    return val; \
4546 } \
4547 EAPI Eina_Bool \
4548 edje_edit_state_container_##CLASS##_##VALUE##_set(Evas_Object *obj, const char *part, const char *state, double value, int new_val) \
4549 { \
4550    GET_PD_OR_RETURN(EINA_FALSE) \
4551    switch (rp->part->type) \
4552      { \
4553       case EDJE_PART_TYPE_TABLE: \
4554       { \
4555          Edje_Part_Description_Table *table; \
4556          table = (Edje_Part_Description_Table *)pd; \
4557          table->table.CLASS.VALUE = new_val; \
4558          break; \
4559       } \
4560       case EDJE_PART_TYPE_BOX: \
4561       { \
4562          Edje_Part_Description_Box *box; \
4563          box = (Edje_Part_Description_Box *)pd; \
4564          box->box.CLASS.VALUE = new_val; \
4565          break; \
4566       } \
4567       default: \
4568         return EINA_FALSE; \
4569      } \
4570    return EINA_TRUE; \
4571 }
4572 
4573 FUNC_CONTAINER_INT(padding, x)
4574 FUNC_CONTAINER_INT(padding, y)
4575 
4576 #undef FUNC_CONTAINER_INT
4577 
4578 #define FUNC_CONTAINER_DOUBLE(CLASS, VALUE) \
4579 EAPI double \
4580 edje_edit_state_container_##CLASS##_##VALUE##_get(Evas_Object *obj, const char *part, const char *state, double value) \
4581 { \
4582    double val; \
4583    GET_PD_OR_RETURN(0.0) \
4584    switch (rp->part->type) \
4585      { \
4586       case EDJE_PART_TYPE_TABLE: \
4587       { \
4588          Edje_Part_Description_Table *table; \
4589          table = (Edje_Part_Description_Table *)pd; \
4590          val = FROM_DOUBLE(table->table.CLASS.VALUE); \
4591          break; \
4592       } \
4593       case EDJE_PART_TYPE_BOX: \
4594       { \
4595          Edje_Part_Description_Box *box; \
4596          box = (Edje_Part_Description_Box *)pd; \
4597          val = FROM_DOUBLE(box->box.CLASS.VALUE); \
4598          break; \
4599       } \
4600       default: \
4601          val = 0.0; \
4602      } \
4603    return val; \
4604 } \
4605 EAPI Eina_Bool \
4606 edje_edit_state_container_##CLASS##_##VALUE##_set(Evas_Object *obj, const char *part, const char *state, double value, double new_val) \
4607 { \
4608    GET_PD_OR_RETURN(EINA_FALSE) \
4609    switch (rp->part->type) \
4610      { \
4611       case EDJE_PART_TYPE_TABLE: \
4612       { \
4613          Edje_Part_Description_Table *table; \
4614          table = (Edje_Part_Description_Table *)pd; \
4615          table->table.CLASS.VALUE = TO_DOUBLE(new_val); \
4616          break; \
4617       } \
4618       case EDJE_PART_TYPE_BOX: \
4619       { \
4620          Edje_Part_Description_Box *box; \
4621          box = (Edje_Part_Description_Box *)pd; \
4622          box->box.CLASS.VALUE = TO_DOUBLE(new_val); \
4623          break; \
4624       } \
4625       default: \
4626         return EINA_FALSE; \
4627      } \
4628    return EINA_TRUE; \
4629 }
4630 
4631 FUNC_CONTAINER_DOUBLE(align, x)
4632 FUNC_CONTAINER_DOUBLE(align, y)
4633 
4634 #undef FUNC_CONTAINER_DOUBLE
4635 
4636 EAPI Eina_Bool
4637 edje_edit_state_container_align_get(Evas_Object *obj, const char *part, const char *state, double value, double *x, double *y)
4638 {
4639    GET_PD_OR_RETURN(EINA_FALSE)
4640 
4641    switch (rp->part->type)
4642      {
4643       case EDJE_PART_TYPE_TABLE:
4644       {
4645          Edje_Part_Description_Table *table;
4646          table = (Edje_Part_Description_Table *)pd;
4647          if (x) *x = FROM_DOUBLE(table->table.align.x);
4648          if (y) *y = FROM_DOUBLE(table->table.align.y);
4649          break;
4650       }
4651 
4652       case EDJE_PART_TYPE_BOX:
4653       {
4654          Edje_Part_Description_Box *box;
4655          box = (Edje_Part_Description_Box *)pd;
4656          if (x) *x = FROM_DOUBLE(box->box.align.x);
4657          if (y) *y = FROM_DOUBLE(box->box.align.y);
4658          break;
4659       }
4660 
4661       default:
4662         return EINA_FALSE;
4663      }
4664    return EINA_TRUE;
4665 }
4666 
4667 EAPI Eina_Bool
edje_edit_state_container_align_set(Evas_Object * obj,const char * part,const char * state,double value,double x,double y)4668 edje_edit_state_container_align_set(Evas_Object *obj, const char *part, const char *state, double value, double x, double y)
4669 {
4670    GET_PD_OR_RETURN(EINA_FALSE)
4671 
4672    switch (rp->part->type)
4673      {
4674       case EDJE_PART_TYPE_TABLE:
4675       {
4676          Edje_Part_Description_Table *table;
4677          table = (Edje_Part_Description_Table *)pd;
4678          table->table.align.x = TO_DOUBLE(x);
4679          table->table.align.y = TO_DOUBLE(y);
4680          break;
4681       }
4682 
4683       case EDJE_PART_TYPE_BOX:
4684       {
4685          Edje_Part_Description_Box *box;
4686          box = (Edje_Part_Description_Box *)pd;
4687          box->box.align.x = x;
4688          box->box.align.y = y;
4689          break;
4690       }
4691 
4692       default:
4693         return EINA_FALSE;
4694      }
4695    return EINA_TRUE;
4696 }
4697 
4698 EAPI Eina_Bool
edje_edit_state_container_padding_get(Evas_Object * obj,const char * part,const char * state,double value,int * x,int * y)4699 edje_edit_state_container_padding_get(Evas_Object *obj, const char *part, const char *state, double value, int *x, int *y)
4700 {
4701    GET_PD_OR_RETURN(EINA_FALSE)
4702 
4703    switch (rp->part->type)
4704      {
4705       case EDJE_PART_TYPE_TABLE:
4706       {
4707          Edje_Part_Description_Table *table;
4708          table = (Edje_Part_Description_Table *)pd;
4709          if (x) *x = table->table.padding.x;
4710          if (y) *y = table->table.padding.y;
4711          break;
4712       }
4713 
4714       case EDJE_PART_TYPE_BOX:
4715       {
4716          Edje_Part_Description_Box *box;
4717          box = (Edje_Part_Description_Box *)pd;
4718          if (x) *x = box->box.padding.x;
4719          if (y) *y = box->box.padding.y;
4720          break;
4721       }
4722 
4723       default:
4724         return EINA_FALSE;
4725      }
4726 
4727    return EINA_TRUE;
4728 }
4729 
4730 EAPI Eina_Bool
edje_edit_state_container_padding_set(Evas_Object * obj,const char * part,const char * state,double value,int x,int y)4731 edje_edit_state_container_padding_set(Evas_Object *obj, const char *part, const char *state, double value, int x, int y)
4732 {
4733    GET_PD_OR_RETURN(EINA_FALSE)
4734 
4735    switch (rp->part->type)
4736      {
4737       case EDJE_PART_TYPE_TABLE:
4738       {
4739          Edje_Part_Description_Table *table;
4740          table = (Edje_Part_Description_Table *)pd;
4741          table->table.padding.x = x;
4742          table->table.padding.y = y;
4743          break;
4744       }
4745 
4746       case EDJE_PART_TYPE_BOX:
4747       {
4748          Edje_Part_Description_Box *box;
4749          box = (Edje_Part_Description_Box *)pd;
4750          box->box.padding.x = x;
4751          box->box.padding.y = y;
4752          break;
4753       }
4754 
4755       default:
4756         return EINA_FALSE;
4757      }
4758    return EINA_TRUE;
4759 }
4760 
4761 EAPI Eina_Bool
edje_edit_state_container_min_get(Evas_Object * obj,const char * part,const char * state,double value,Eina_Bool * h,Eina_Bool * v)4762 edje_edit_state_container_min_get(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool *h, Eina_Bool *v)
4763 {
4764    GET_PD_OR_RETURN(EINA_FALSE)
4765 
4766    switch (rp->part->type)
4767      {
4768       case EDJE_PART_TYPE_TABLE:
4769       {
4770          Edje_Part_Description_Table *table;
4771          table = (Edje_Part_Description_Table *)pd;
4772          if (h) *h = table->table.min.h;
4773          if (v) *v = table->table.min.v;
4774          break;
4775       }
4776 
4777       case EDJE_PART_TYPE_BOX:
4778       {
4779          Edje_Part_Description_Box *box;
4780          box = (Edje_Part_Description_Box *)pd;
4781          if (h) *h = box->box.min.h;
4782          if (v) *v = box->box.min.v;
4783          break;
4784       }
4785 
4786       default:
4787         return EINA_FALSE;
4788      }
4789 
4790    return EINA_TRUE;
4791 }
4792 
4793 EAPI Eina_Bool
edje_edit_state_container_min_set(Evas_Object * obj,const char * part,const char * state,double value,Eina_Bool h,Eina_Bool v)4794 edje_edit_state_container_min_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool h, Eina_Bool v)
4795 {
4796    GET_PD_OR_RETURN(EINA_FALSE)
4797 
4798    switch (rp->part->type)
4799      {
4800       case EDJE_PART_TYPE_TABLE:
4801       {
4802          Edje_Part_Description_Table *table;
4803          table = (Edje_Part_Description_Table *)pd;
4804          table->table.min.h = h;
4805          table->table.min.v = v;
4806          break;
4807       }
4808 
4809       case EDJE_PART_TYPE_BOX:
4810       {
4811          Edje_Part_Description_Box *box;
4812          box = (Edje_Part_Description_Box *)pd;
4813          box->box.min.h = h;
4814          box->box.min.v = v;
4815          break;
4816       }
4817 
4818       default:
4819         return EINA_FALSE;
4820      }
4821    return EINA_TRUE;
4822 }
4823 
4824 /***************************/
4825 /*  BOX & TABLE ITEMS API  */
4826 /***************************/
4827 
4828 static void
_edje_edit_part_item_insert(Edje_Part * ep,unsigned int item_position,const char * item_name,const char * source_group)4829 _edje_edit_part_item_insert(Edje_Part *ep, unsigned int item_position, const char *item_name, const char *source_group)
4830 {
4831    Edje_Pack_Element *item;
4832    unsigned int i;
4833 
4834    ep->items_count++;
4835    ep->items = realloc(ep->items, sizeof (Edje_Pack_Element *) * ep->items_count);
4836    item = _alloc(sizeof (Edje_Pack_Element));
4837    /* shift all items to the end */
4838    for (i = ep->items_count - 1; i > item_position; i--)
4839      ep->items[i] = ep->items[i - 1];
4840    ep->items[item_position] = item;
4841 
4842    item->type = EDJE_PART_TYPE_GROUP;
4843    item->name = eina_stringshare_add(item_name);
4844    item->source = eina_stringshare_add(source_group);
4845    item->min.w = 0;
4846    item->min.h = 0;
4847    item->prefer.w = 0;
4848    item->prefer.h = 0;
4849    item->max.w = -1;
4850    item->max.h = -1;
4851    item->padding.l = 0;
4852    item->padding.r = 0;
4853    item->padding.t = 0;
4854    item->padding.b = 0;
4855    item->align.x = FROM_DOUBLE(0.5);
4856    item->align.y = FROM_DOUBLE(0.5);
4857    item->weight.x = FROM_DOUBLE(0.0);
4858    item->weight.y = FROM_DOUBLE(0.0);
4859    item->aspect.w = 0;
4860    item->aspect.h = 0;
4861    item->aspect.mode = EDJE_ASPECT_CONTROL_NONE;
4862    item->options = NULL;
4863    item->col = -1;
4864    item->row = -1;
4865    item->colspan = 1;
4866    item->rowspan = 1;
4867    item->spread.w = 1;
4868    item->spread.h = 1;
4869 }
4870 
4871 EAPI Eina_Bool
edje_edit_part_item_append(Evas_Object * obj,const char * part,const char * item_name,const char * source_group)4872 edje_edit_part_item_append(Evas_Object *obj, const char *part, const char *item_name, const char *source_group)
4873 {
4874    Edje_Part *ep;
4875    unsigned int i;
4876 
4877    GET_RP_OR_RETURN(EINA_FALSE);
4878 
4879    /* There is only Box and Table is allowed. */
4880    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
4881        (rp->part->type != EDJE_PART_TYPE_TABLE))
4882      return EINA_FALSE;
4883 
4884    ep = rp->part;
4885 
4886    if (!ed->file) return EINA_FALSE;
4887 
4888    /* check if a source group is exists. */
4889    if (!eina_hash_find(ed->file->collection, source_group))
4890      return EINA_FALSE;
4891 
4892    for (i = 0; i < ep->items_count; ++i)
4893      {
4894         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
4895           return EINA_FALSE;
4896      }
4897 
4898    _edje_edit_part_item_insert(ep, ep->items_count, item_name, source_group);
4899 
4900    return EINA_TRUE;
4901 }
4902 
4903 /* deprecated */
4904 EAPI Eina_Bool
edje_edit_part_item_insert_before(Evas_Object * obj,const char * part,const char * item_name,const char * item_before,const char * source_group)4905 edje_edit_part_item_insert_before(Evas_Object *obj, const char *part, const char *item_name, const char *item_before, const char *source_group)
4906 {
4907    Edje_Part *ep;
4908    unsigned int i;
4909    int item_before_position = -1;
4910 
4911    GET_RP_OR_RETURN(EINA_FALSE);
4912 
4913    /* There is only Box and Table is allowed. */
4914    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
4915        (rp->part->type != EDJE_PART_TYPE_TABLE))
4916      return EINA_FALSE;
4917 
4918    ep = rp->part;
4919 
4920    if (!ed->file) return EINA_FALSE;
4921 
4922    /* check if a source group is exists. */
4923    if (!eina_hash_find(ed->file->collection, source_group))
4924      return EINA_FALSE;
4925 
4926    for (i = 0; i < ep->items_count; ++i)
4927      {
4928         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
4929           return EINA_FALSE;
4930         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_before)))
4931           item_before_position = i;
4932      }
4933 
4934    if (item_before_position == -1) return EINA_FALSE;
4935 
4936    _edje_edit_part_item_insert(ep, (unsigned)item_before_position, item_name, source_group);
4937 
4938    return EINA_TRUE;
4939 }
4940 
4941 EAPI Eina_Bool
edje_edit_part_item_insert_before_index(Evas_Object * obj,const char * part,const char * item_name,unsigned int index,const char * source_group)4942 edje_edit_part_item_insert_before_index(Evas_Object *obj, const char *part, const char *item_name, unsigned int index, const char *source_group)
4943 {
4944    Edje_Part *ep;
4945 
4946    GET_RP_OR_RETURN(EINA_FALSE);
4947 
4948    /* There is only Box and Table is allowed. */
4949    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
4950        (rp->part->type != EDJE_PART_TYPE_TABLE))
4951      return EINA_FALSE;
4952 
4953    ep = rp->part;
4954 
4955    if (!ed->file) return EINA_FALSE;
4956 
4957    /* check if a source group is exists. */
4958    if (!eina_hash_find(ed->file->collection, source_group))
4959      return EINA_FALSE;
4960 
4961    _edje_edit_part_item_insert(ep, index, item_name, source_group);
4962 
4963    return EINA_TRUE;
4964 }
4965 
4966 /* deprecated */
4967 EAPI Eina_Bool
edje_edit_part_item_insert_after(Evas_Object * obj,const char * part,const char * item_name,const char * item_after,const char * source_group)4968 edje_edit_part_item_insert_after(Evas_Object *obj, const char *part, const char *item_name, const char *item_after, const char *source_group)
4969 {
4970    Edje_Part *ep;
4971    unsigned int i;
4972    int item_after_position = -1;
4973 
4974    GET_RP_OR_RETURN(EINA_FALSE);
4975 
4976    /* There is only Box and Table is allowed. */
4977    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
4978        (rp->part->type != EDJE_PART_TYPE_TABLE))
4979      return EINA_FALSE;
4980 
4981    ep = rp->part;
4982 
4983    if (!ed->file) return EINA_FALSE;
4984 
4985    /* check if a source group is exists. */
4986    if (!eina_hash_find(ed->file->collection, source_group))
4987      return EINA_FALSE;
4988 
4989    for (i = 0; i < ep->items_count; ++i)
4990      {
4991         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
4992           return EINA_FALSE;
4993         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_after)))
4994           item_after_position = i;
4995      }
4996 
4997    if (item_after_position == -1) return EINA_FALSE;
4998 
4999    item_after_position++;
5000    _edje_edit_part_item_insert(ep, (unsigned)item_after_position, item_name, source_group);
5001 
5002    return EINA_TRUE;
5003 }
5004 
5005 EAPI Eina_Bool
edje_edit_part_item_insert_after_index(Evas_Object * obj,const char * part,const char * item_name,unsigned int index,const char * source_group)5006 edje_edit_part_item_insert_after_index(Evas_Object *obj, const char *part, const char *item_name, unsigned int index, const char *source_group)
5007 {
5008    Edje_Part *ep;
5009 
5010    GET_RP_OR_RETURN(EINA_FALSE);
5011 
5012    /* There is only Box and Table is allowed. */
5013    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5014        (rp->part->type != EDJE_PART_TYPE_TABLE))
5015      return EINA_FALSE;
5016 
5017    ep = rp->part;
5018 
5019    if (!ed->file) return EINA_FALSE;
5020 
5021    /* check if a source group is exists. */
5022    if (!eina_hash_find(ed->file->collection, source_group))
5023      return EINA_FALSE;
5024 
5025    _edje_edit_part_item_insert(ep, index, item_name, source_group);
5026 
5027    return EINA_TRUE;
5028 }
5029 
5030 /* deprecated */
5031 EAPI Eina_Bool
edje_edit_part_item_insert_at(Evas_Object * obj,const char * part,const char * item_name,const char * source_group,unsigned int place)5032 edje_edit_part_item_insert_at(Evas_Object *obj, const char *part, const char *item_name, const char *source_group, unsigned int place)
5033 {
5034    Edje_Part *ep;
5035    unsigned int i;
5036 
5037    GET_RP_OR_RETURN(EINA_FALSE);
5038 
5039    /* There is only Box and Table is allowed. */
5040    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5041        (rp->part->type != EDJE_PART_TYPE_TABLE))
5042      return EINA_FALSE;
5043 
5044    ep = rp->part;
5045    if (place > ep->items_count - 1)
5046      return EINA_FALSE;
5047 
5048    if (!ed->file) return EINA_FALSE;
5049 
5050    /* check if a source group is exists. */
5051    if (!eina_hash_find(ed->file->collection, source_group))
5052      return EINA_FALSE;
5053 
5054    for (i = 0; i < ep->items_count; ++i)
5055      {
5056         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
5057           return EINA_FALSE;
5058      }
5059 
5060    _edje_edit_part_item_insert(ep, place, item_name, source_group);
5061 
5062    return EINA_TRUE;
5063 }
5064 
5065 /* deprecated */
5066 EAPI Eina_Bool
edje_edit_part_item_move_below(Evas_Object * obj,const char * part,const char * item_name)5067 edje_edit_part_item_move_below(Evas_Object *obj, const char *part, const char *item_name)
5068 {
5069    Edje_Part *ep;
5070    unsigned int i;
5071    Edje_Pack_Element *item;
5072    unsigned int item_place = 0;
5073 
5074    GET_RP_OR_RETURN(EINA_FALSE);
5075 
5076    /* There is only Box and Table is allowed. */
5077    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5078        (rp->part->type != EDJE_PART_TYPE_TABLE))
5079      return EINA_FALSE;
5080 
5081    ep = rp->part;
5082 
5083    if (!ed->file) return EINA_FALSE;
5084 
5085    for (i = 0; i < ep->items_count; ++i)
5086      {
5087         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
5088           {
5089              item_place = i;
5090              break;
5091           }
5092      }
5093 
5094    if (!item_place)
5095      return EINA_FALSE;
5096 
5097    item = ep->items[item_place - 1];
5098    ep->items[item_place - 1] = ep->items[item_place];
5099    ep->items[item_place] = item;
5100 
5101    return EINA_TRUE;
5102 }
5103 
5104 EAPI Eina_Bool
edje_edit_part_item_move_below_index(Evas_Object * obj,const char * part,unsigned int index)5105 edje_edit_part_item_move_below_index(Evas_Object *obj, const char *part, unsigned int index)
5106 {
5107    Edje_Part *ep;
5108    Edje_Pack_Element *item;
5109 
5110    GET_RP_OR_RETURN(EINA_FALSE);
5111 
5112    /* There is only Box and Table is allowed. */
5113    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5114        (rp->part->type != EDJE_PART_TYPE_TABLE))
5115      return EINA_FALSE;
5116 
5117    ep = rp->part;
5118 
5119    if (!ed->file) return EINA_FALSE;
5120 
5121    item = ep->items[index - 1];
5122    ep->items[index - 1] = ep->items[index];
5123    ep->items[index] = item;
5124 
5125    return EINA_TRUE;
5126 }
5127 
5128 /* deprecated */
5129 EAPI Eina_Bool
edje_edit_part_item_move_above(Evas_Object * obj,const char * part,const char * item_name)5130 edje_edit_part_item_move_above(Evas_Object *obj, const char *part, const char *item_name)
5131 {
5132    Edje_Part *ep;
5133    unsigned int i;
5134    Edje_Pack_Element *item;
5135    unsigned int item_place = 0;
5136 
5137    GET_RP_OR_RETURN(EINA_FALSE);
5138 
5139    /* There is only Box and Table is allowed. */
5140    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5141        (rp->part->type != EDJE_PART_TYPE_TABLE))
5142      return EINA_FALSE;
5143 
5144    ep = rp->part;
5145 
5146    if (!ed->file) return EINA_FALSE;
5147 
5148    for (i = 0; i < ep->items_count; ++i)
5149      {
5150         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
5151           {
5152              item_place = i;
5153              break;
5154           }
5155      }
5156 
5157    if (item_place == ep->items_count - 1)
5158      return EINA_FALSE;
5159 
5160    item = ep->items[item_place + 1];
5161    ep->items[item_place + 1] = ep->items[item_place];
5162    ep->items[item_place] = item;
5163 
5164    return EINA_TRUE;
5165 }
5166 
5167 EAPI Eina_Bool
edje_edit_part_item_move_above_index(Evas_Object * obj,const char * part,unsigned int index)5168 edje_edit_part_item_move_above_index(Evas_Object *obj, const char *part, unsigned int index)
5169 {
5170    Edje_Part *ep;
5171    Edje_Pack_Element *item;
5172 
5173    GET_RP_OR_RETURN(EINA_FALSE);
5174 
5175    /* There is only Box and Table is allowed. */
5176    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5177        (rp->part->type != EDJE_PART_TYPE_TABLE))
5178      return EINA_FALSE;
5179 
5180    ep = rp->part;
5181 
5182    if (!ed->file) return EINA_FALSE;
5183 
5184    item = ep->items[index + 1];
5185    ep->items[index + 1] = ep->items[index];
5186    ep->items[index] = item;
5187 
5188    return EINA_TRUE;
5189 }
5190 
5191 /* deprecated */
5192 EAPI Eina_List *
edje_edit_part_items_list_get(Evas_Object * obj,const char * part)5193 edje_edit_part_items_list_get(Evas_Object *obj, const char *part)
5194 {
5195    Edje_Part *ep;
5196    unsigned int i;
5197    Eina_List *items_list = NULL;
5198    GET_RP_OR_RETURN(NULL);
5199    /* There is only Box and Table is allowed. */
5200    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5201        (rp->part->type != EDJE_PART_TYPE_TABLE))
5202      return NULL;
5203    ep = rp->part;
5204    if (!ed->file) return NULL;
5205 
5206    for (i = 0; i < ep->items_count; ++i)
5207      items_list = eina_list_append(items_list,
5208                                    eina_stringshare_add(ep->items[i]->name));
5209 
5210    return items_list;
5211 }
5212 
5213 EAPI int
edje_edit_part_items_count_get(Evas_Object * obj,const char * part)5214 edje_edit_part_items_count_get(Evas_Object *obj, const char *part)
5215 {
5216    Edje_Part *ep;
5217 
5218    GET_RP_OR_RETURN(-1);
5219    /* There is only Box and Table is allowed. */
5220    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5221        (rp->part->type != EDJE_PART_TYPE_TABLE))
5222      return -1;
5223 
5224    ep = rp->part;
5225    if (!ed->file) return -1;
5226 
5227    return  ep->items_count;
5228 }
5229 
5230 /* deprecated */
5231 EAPI Eina_Bool
edje_edit_part_item_del(Evas_Object * obj,const char * part,const char * name)5232 edje_edit_part_item_del(Evas_Object *obj, const char *part, const char *name)
5233 {
5234    Edje_Part *ep;
5235    Edje_Pack_Element *item;
5236    unsigned int i;
5237    GET_RP_OR_RETURN(EINA_FALSE);
5238    /* There is only Box and Table is allowed. */
5239    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5240        (rp->part->type != EDJE_PART_TYPE_TABLE))
5241      return EINA_FALSE;
5242    ep = rp->part;
5243    if (!ed->file) return EINA_FALSE;
5244 
5245    for (i = 0; i < ep->items_count; ++i)
5246      {
5247         item = ep->items[i];
5248         if (!strcmp(name, item->name))
5249           break;
5250      }
5251    if (i == ep->items_count)
5252      {
5253         WRN("Unable to delete item \"%s\". It does not exist.", name);
5254         return EINA_FALSE;
5255      }
5256 
5257    {
5258       Edje_Pack_Element **tmp;
5259       _edje_if_string_free(ed, &item->name);
5260       --ep->items_count;
5261 
5262       while (i < ep->items_count)
5263         {
5264            ep->items[i] = ep->items[i + 1];
5265            i++;
5266         }
5267 
5268       if (ep->items_count != 0)
5269         {
5270            tmp = realloc(ep->items, sizeof(Edje_Pack_Element *) * ep->items_count);
5271            if (!tmp)
5272              {
5273                 free(item);
5274                 return EINA_FALSE;
5275              }
5276            ep->items = tmp;
5277         }
5278       else
5279         ep->items = NULL;
5280    }
5281 
5282    GET_EED_OR_RETURN(EINA_FALSE);
5283    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
5284 
5285    return EINA_TRUE;
5286 }
5287 
5288 EAPI Eina_Bool
edje_edit_part_item_index_del(Evas_Object * obj,const char * part,unsigned int index)5289 edje_edit_part_item_index_del(Evas_Object *obj, const char *part, unsigned int index)
5290 {
5291    Edje_Part *ep;
5292    Edje_Pack_Element *item;
5293 
5294    GET_RP_OR_RETURN(EINA_FALSE);
5295    /* There is only Box and Table is allowed. */
5296    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5297        (rp->part->type != EDJE_PART_TYPE_TABLE))
5298      return EINA_FALSE;
5299    ep = rp->part;
5300    if (!ed->file) return EINA_FALSE;
5301 
5302    item = ep->items[index];
5303    {
5304       Edje_Pack_Element **tmp;
5305       _edje_if_string_free(ed, &item->name);
5306       --ep->items_count;
5307 
5308       while (index < ep->items_count)
5309         {
5310            ep->items[index] = ep->items[index + 1];
5311            index++;
5312         }
5313 
5314       if (ep->items_count != 0)
5315         {
5316            tmp = realloc(ep->items, sizeof(Edje_Pack_Element *) * ep->items_count);
5317            if (!tmp)
5318              {
5319                 free(item);
5320                 return EINA_FALSE;
5321              }
5322            ep->items = tmp;
5323         }
5324       else
5325         ep->items = NULL;
5326    }
5327 
5328    GET_EED_OR_RETURN(EINA_FALSE);
5329    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
5330 
5331    return EINA_TRUE;
5332 }
5333 
5334 EAPI Eina_Bool
edje_edit_part_item_index_name_set(Evas_Object * obj,const char * part,unsigned int index,const char * name)5335 edje_edit_part_item_index_name_set(Evas_Object *obj, const char *part, unsigned int index, const char *name)
5336 {
5337    Edje_Part *ep;
5338    unsigned int i;
5339 
5340    GET_RP_OR_RETURN(EINA_FALSE);
5341 
5342    /* There is only Box and Table is allowed. */
5343    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5344        (rp->part->type != EDJE_PART_TYPE_TABLE))
5345      return EINA_FALSE;
5346    if (rp->part->items_count < index)
5347      return EINA_FALSE;
5348 
5349    ep = rp->part;
5350 
5351    if (!ed->file) return EINA_FALSE;
5352 
5353    /* check if a part with given name is exists. */
5354    for (i = 0; i < ep->items_count; ++i)
5355      {
5356         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, name)))
5357           return EINA_FALSE;
5358      }
5359 
5360    eina_stringshare_del(ep->items[index]->name);
5361    ep->items[index]->name = eina_stringshare_add(name);
5362 
5363    return EINA_TRUE;
5364 }
5365 
5366 EAPI const char *
edje_edit_part_item_index_name_get(Evas_Object * obj,const char * part,unsigned int index)5367 edje_edit_part_item_index_name_get(Evas_Object *obj, const char *part, unsigned int index)
5368 {
5369    Edje_Part *ep;
5370 
5371    GET_RP_OR_RETURN(NULL);
5372 
5373    /* There is only Box and Table is allowed. */
5374    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5375        (rp->part->type != EDJE_PART_TYPE_TABLE))
5376      return NULL;
5377    if (rp->part->items_count < index)
5378      return NULL;
5379 
5380    ep = rp->part;
5381 
5382    if (!ed->file) return NULL;
5383 
5384    return eina_stringshare_add(ep->items[index]->name);
5385 }
5386 
5387 /* deprecated */
5388 EAPI Eina_Bool
edje_edit_part_item_source_set(Evas_Object * obj,const char * part,const char * item_name,const char * source_group)5389 edje_edit_part_item_source_set(Evas_Object *obj, const char *part, const char *item_name, const char *source_group)
5390 {
5391    Edje_Part *ep;
5392    unsigned int i;
5393    Edje_Pack_Element *item = NULL;
5394 
5395    GET_RP_OR_RETURN(EINA_FALSE);
5396 
5397    /* There is only Box and Table is allowed. */
5398    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5399        (rp->part->type != EDJE_PART_TYPE_TABLE))
5400      return EINA_FALSE;
5401 
5402    ep = rp->part;
5403 
5404    if (!ed->file) return EINA_FALSE;
5405 
5406    /* check if a source group is exists. */
5407    if (!eina_hash_find(ed->file->collection, source_group))
5408      return EINA_FALSE;
5409 
5410    /* check if item is exists and get it. */
5411    for (i = 0; i < ep->items_count; ++i)
5412      {
5413         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
5414           {
5415              item = ep->items[i];
5416              break;
5417           }
5418      }
5419    if (!item) return EINA_FALSE;
5420 
5421    item->source = eina_stringshare_add(source_group);
5422 
5423    return EINA_TRUE;
5424 }
5425 
5426 EAPI Eina_Bool
edje_edit_part_item_index_source_set(Evas_Object * obj,const char * part,unsigned int index,const char * source_group)5427 edje_edit_part_item_index_source_set(Evas_Object *obj, const char *part, unsigned int index, const char *source_group)
5428 {
5429    Edje_Part *ep;
5430 
5431    GET_RP_OR_RETURN(EINA_FALSE);
5432 
5433    /* There is only Box and Table is allowed. */
5434    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5435        (rp->part->type != EDJE_PART_TYPE_TABLE))
5436      return EINA_FALSE;
5437 
5438    ep = rp->part;
5439 
5440    if (!ed->file) return EINA_FALSE;
5441 
5442    /* check if a source group is exists. */
5443    if (!eina_hash_find(ed->file->collection, source_group))
5444      return EINA_FALSE;
5445 
5446    ep->items[index]->source = eina_stringshare_add(source_group);
5447 
5448    return EINA_TRUE;
5449 }
5450 
5451 EINA_DEPRECATED
5452 EAPI const char *
edje_edit_part_item_source_get(Evas_Object * obj,const char * part,const char * item_name)5453 edje_edit_part_item_source_get(Evas_Object *obj, const char *part, const char *item_name)
5454 {
5455    Edje_Part *ep;
5456    unsigned int i;
5457    Edje_Pack_Element *item = NULL;
5458 
5459    GET_RP_OR_RETURN(NULL);
5460 
5461    /* There is only Box and Table is allowed. */
5462    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5463        (rp->part->type != EDJE_PART_TYPE_TABLE))
5464      return NULL;
5465 
5466    ep = rp->part;
5467 
5468    if (!ed->file) return NULL;
5469 
5470    /* check if item is exists and get it. */
5471    for (i = 0; i < ep->items_count; ++i)
5472      {
5473         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
5474           {
5475              item = ep->items[i];
5476              break;
5477           }
5478      }
5479    if (!item) return NULL;
5480 
5481    return eina_stringshare_add(item->source);
5482 }
5483 
5484 EAPI const char *
edje_edit_part_item_index_source_get(Evas_Object * obj,const char * part,unsigned int index)5485 edje_edit_part_item_index_source_get(Evas_Object *obj, const char *part, unsigned int index)
5486 {
5487    Edje_Part *ep;
5488 
5489    GET_RP_OR_RETURN(NULL);
5490 
5491    /* There is only Box and Table is allowed. */
5492    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5493        (rp->part->type != EDJE_PART_TYPE_TABLE))
5494      return NULL;
5495 
5496    ep = rp->part;
5497 
5498    if (!ed->file) return NULL;
5499 
5500    return eina_stringshare_add(ep->items[index]->source);
5501 }
5502 
5503 /* deprecated */
5504 #define FUNC_PART_ITEM_INT(Class, Value, Min)                                                                    \
5505   EAPI int                                                                                                       \
5506   edje_edit_part_item_##Class##_##Value##_get(Evas_Object * obj, const char *part, const char *item_name)        \
5507   {                                                                                                              \
5508      Edje_Part *ep;                                                                                              \
5509      unsigned int i;                                                                                             \
5510      Edje_Pack_Element *item = NULL;                                                                             \
5511      if ((!obj) || (!part) || (!item_name))                                                                      \
5512        return Min;                                                                                               \
5513      GET_RP_OR_RETURN(Min);                                                                                      \
5514      ep = rp->part;                                                                                              \
5515      for (i = 0; i < ep->items_count; ++i)                                                                       \
5516        {                                                                                                         \
5517           if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))                                    \
5518             {                                                                                                    \
5519                item = ep->items[i];                                                                              \
5520                break;                                                                                            \
5521             }                                                                                                    \
5522        }                                                                                                         \
5523      if (!item) return Min;                                                                                      \
5524      return item->Class.Value;                                                                                   \
5525   }                                                                                                              \
5526   EAPI Eina_Bool                                                                                                 \
5527   edje_edit_part_item_##Class##_##Value##_set(Evas_Object * obj, const char *part, const char *item_name, int v) \
5528   {                                                                                                              \
5529      Edje_Part *ep;                                                                                              \
5530      unsigned int i;                                                                                             \
5531      Edje_Pack_Element *item = NULL;                                                                             \
5532      if ((!obj) || (!part) || (!item_name))                                                                      \
5533        return EINA_FALSE;                                                                                        \
5534      if (v < Min) return EINA_FALSE;                                                                             \
5535      GET_RP_OR_RETURN(EINA_FALSE);                                                                               \
5536      ep = rp->part;                                                                                              \
5537      if ((rp->part->type != EDJE_PART_TYPE_BOX) &&                                                               \
5538          (rp->part->type != EDJE_PART_TYPE_TABLE))                                                               \
5539        return EINA_FALSE;                                                                                        \
5540      for (i = 0; i < ep->items_count; ++i)                                                                       \
5541        {                                                                                                         \
5542           if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))                                    \
5543             {                                                                                                    \
5544                item = ep->items[i];                                                                              \
5545                break;                                                                                            \
5546             }                                                                                                    \
5547        }                                                                                                         \
5548      if (!item) return EINA_FALSE;                                                                               \
5549      item->Class.Value = v;                                                                                      \
5550      return EINA_TRUE;                                                                                           \
5551   }
5552 
5553 FUNC_PART_ITEM_INT(min, w, 0);
5554 FUNC_PART_ITEM_INT(min, h, 0);
5555 FUNC_PART_ITEM_INT(max, w, -1);
5556 FUNC_PART_ITEM_INT(max, h, -1);
5557 FUNC_PART_ITEM_INT(aspect, w, 0);
5558 FUNC_PART_ITEM_INT(aspect, h, 0);
5559 FUNC_PART_ITEM_INT(prefer, w, 0);
5560 FUNC_PART_ITEM_INT(prefer, h, 0);
5561 FUNC_PART_ITEM_INT(spread, w, 0);
5562 FUNC_PART_ITEM_INT(spread, h, 0);
5563 
5564 #define FUNC_PART_ITEM_INDEX_INT(Class, Value, Min)                                                                 \
5565   EAPI int                                                                                                          \
5566   edje_edit_part_item_index_##Class##_##Value##_get(Evas_Object * obj, const char *part, unsigned int index)        \
5567   {                                                                                                                 \
5568      Edje_Part *ep;                                                                                                 \
5569      if ((!obj) || (!part))                                                                                         \
5570        return Min;                                                                                                  \
5571      GET_RP_OR_RETURN(Min);                                                                                         \
5572      ep = rp->part;                                                                                                 \
5573      if (index >= ep->items_count)                                                                                  \
5574        return Min;                                                                                                  \
5575      return ep->items[index]->Class.Value;                                                                          \
5576   }                                                                                                                 \
5577   EAPI Eina_Bool                                                                                                    \
5578   edje_edit_part_item_index_##Class##_##Value##_set(Evas_Object * obj, const char *part, unsigned int index, int v) \
5579   {                                                                                                                 \
5580      Edje_Part *ep;                                                                                                 \
5581      if ((!obj) || (!part))                                                                                         \
5582        return EINA_FALSE;                                                                                           \
5583      if (v < Min) return EINA_FALSE;                                                                                \
5584      GET_RP_OR_RETURN(EINA_FALSE);                                                                                  \
5585      ep = rp->part;                                                                                                 \
5586      if ((rp->part->type != EDJE_PART_TYPE_BOX) &&                                                                  \
5587          (rp->part->type != EDJE_PART_TYPE_TABLE))                                                                  \
5588        return EINA_FALSE;                                                                                           \
5589      if (index >= ep->items_count)                                                                                  \
5590        return Min;                                                                                                  \
5591      ep->items[index]->Class.Value = v;                                                                             \
5592      return EINA_TRUE;                                                                                              \
5593   }
5594 
5595 FUNC_PART_ITEM_INDEX_INT(min, w, 0);
5596 FUNC_PART_ITEM_INDEX_INT(min, h, 0);
5597 FUNC_PART_ITEM_INDEX_INT(max, w, -1);
5598 FUNC_PART_ITEM_INDEX_INT(max, h, -1);
5599 FUNC_PART_ITEM_INDEX_INT(aspect, w, 0);
5600 FUNC_PART_ITEM_INDEX_INT(aspect, h, 0);
5601 FUNC_PART_ITEM_INDEX_INT(prefer, w, 0);
5602 FUNC_PART_ITEM_INDEX_INT(prefer, h, 0);
5603 FUNC_PART_ITEM_INDEX_INT(spread, w, 0);
5604 FUNC_PART_ITEM_INDEX_INT(spread, h, 0);
5605 
5606 /* deprecated */
5607 EAPI Edje_Aspect_Control
edje_edit_part_item_aspect_mode_get(Evas_Object * obj,const char * part,const char * item_name)5608 edje_edit_part_item_aspect_mode_get(Evas_Object *obj, const char *part, const char *item_name)
5609 {
5610    Edje_Part *ep;
5611    unsigned int i;
5612    Edje_Pack_Element *item = NULL;
5613 
5614    if ((!obj) || (!part) || (!item_name))
5615      return EDJE_ASPECT_CONTROL_NONE;
5616 
5617    GET_RP_OR_RETURN(EDJE_ASPECT_CONTROL_NONE);
5618 
5619    ep = rp->part;
5620    for (i = 0; i < ep->items_count; ++i)
5621      {
5622         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
5623           {
5624              item = ep->items[i];
5625              break;
5626           }
5627      }
5628    if (!item) return EDJE_ASPECT_CONTROL_NONE;
5629 
5630    return item->aspect.mode;
5631 }
5632 
5633 /* deprecated */
5634 EAPI Eina_Bool
edje_edit_part_item_aspect_mode_set(Evas_Object * obj,const char * part,const char * item_name,Edje_Aspect_Control mode)5635 edje_edit_part_item_aspect_mode_set(Evas_Object *obj, const char *part, const char *item_name, Edje_Aspect_Control mode)
5636 {
5637    Edje_Part *ep;
5638    unsigned int i;
5639    Edje_Pack_Element *item = NULL;
5640 
5641    if ((!obj) || (!part) || (!item_name))
5642      return EINA_FALSE;
5643 
5644    GET_RP_OR_RETURN(EINA_FALSE);
5645 
5646    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5647        (rp->part->type != EDJE_PART_TYPE_TABLE))
5648      return EINA_FALSE;
5649 
5650    ep = rp->part;
5651 
5652    for (i = 0; i < ep->items_count; ++i)
5653      {
5654         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
5655           {
5656              item = ep->items[i];
5657              break;
5658           }
5659      }
5660    if (!item) return EINA_FALSE;
5661 
5662    item->aspect.mode = mode;
5663 
5664    return EINA_TRUE;
5665 }
5666 
5667 EAPI Edje_Aspect_Control
edje_edit_part_item_index_aspect_mode_get(Evas_Object * obj,const char * part,unsigned int index)5668 edje_edit_part_item_index_aspect_mode_get(Evas_Object *obj, const char *part, unsigned int index)
5669 {
5670    Edje_Part *ep;
5671 
5672    if ((!obj) || (!part))
5673      return EDJE_ASPECT_CONTROL_NONE;
5674 
5675    GET_RP_OR_RETURN(EDJE_ASPECT_CONTROL_NONE);
5676 
5677    ep = rp->part;
5678    if (index >= ep->items_count)
5679      return EDJE_ASPECT_CONTROL_NONE;
5680 
5681    return ep->items[index]->aspect.mode;
5682 }
5683 
5684 EAPI Eina_Bool
edje_edit_part_item_index_aspect_mode_set(Evas_Object * obj,const char * part,unsigned int index,Edje_Aspect_Control mode)5685 edje_edit_part_item_index_aspect_mode_set(Evas_Object *obj, const char *part, unsigned int index, Edje_Aspect_Control mode)
5686 {
5687    Edje_Part *ep;
5688 
5689    if ((!obj) || (!part))
5690      return EINA_FALSE;
5691 
5692    GET_RP_OR_RETURN(EINA_FALSE);
5693 
5694    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
5695        (rp->part->type != EDJE_PART_TYPE_TABLE))
5696      return EINA_FALSE;
5697 
5698    ep = rp->part;
5699 
5700    if (index >= ep->items_count)
5701      return EINA_FALSE;
5702 
5703    ep->items[index]->aspect.mode = mode;
5704 
5705    return EINA_TRUE;
5706 }
5707 
5708 /* deprecated */
5709 EAPI Eina_Bool
edje_edit_part_item_padding_get(Evas_Object * obj,const char * part,const char * item_name,int * l,int * r,int * t,int * b)5710 edje_edit_part_item_padding_get(Evas_Object *obj, const char *part, const char *item_name, int *l, int *r, int *t, int *b)
5711 {
5712    Edje_Part *ep;
5713    unsigned int i;
5714    Edje_Pack_Element *item = NULL;
5715 
5716    if ((!obj) || (!part) || (!item_name))
5717      return EINA_FALSE;
5718 
5719    GET_RP_OR_RETURN(EINA_FALSE);
5720 
5721    ep = rp->part;
5722    for (i = 0; i < ep->items_count; ++i)
5723      {
5724         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
5725           {
5726              item = ep->items[i];
5727              break;
5728           }
5729      }
5730    if (!item) return EINA_FALSE;
5731 
5732    if (l) *l = item->padding.l;
5733    if (t) *t = item->padding.t;
5734    if (r) *r = item->padding.r;
5735    if (b) *b = item->padding.b;
5736 
5737    return EINA_TRUE;
5738 }
5739 
5740 /* deprecated */
5741 EAPI Eina_Bool
edje_edit_part_item_padding_set(Evas_Object * obj,const char * part,const char * item_name,int l,int r,int t,int b)5742 edje_edit_part_item_padding_set(Evas_Object *obj, const char *part, const char *item_name, int l, int r, int t, int b)
5743 {
5744    Edje_Part *ep;
5745    unsigned int i;
5746    Edje_Pack_Element *item = NULL;
5747 
5748    if ((!obj) || (!part) || (!item_name))
5749      return EINA_FALSE;
5750 
5751    GET_RP_OR_RETURN(EINA_FALSE);
5752 
5753    ep = rp->part;
5754    for (i = 0; i < ep->items_count; ++i)
5755      {
5756         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
5757           {
5758              item = ep->items[i];
5759              break;
5760           }
5761      }
5762    if (!item) return EINA_FALSE;
5763 
5764    if (l > -1) item->padding.l = l;
5765    else return EINA_FALSE;
5766    if (t > -1) item->padding.t = t;
5767    else return EINA_FALSE;
5768    if (r > -1) item->padding.r = r;
5769    else return EINA_FALSE;
5770    if (b > -1) item->padding.b = b;
5771    else return EINA_FALSE;
5772 
5773    return EINA_TRUE;
5774 }
5775 
5776 EAPI Eina_Bool
edje_edit_part_item_index_padding_get(Evas_Object * obj,const char * part,unsigned int index,int * l,int * r,int * t,int * b)5777 edje_edit_part_item_index_padding_get(Evas_Object *obj, const char *part, unsigned int index, int *l, int *r, int *t, int *b)
5778 {
5779    Edje_Part *ep;
5780 
5781    if ((!obj) || (!part))
5782      return EINA_FALSE;
5783 
5784    GET_RP_OR_RETURN(EINA_FALSE);
5785 
5786    ep = rp->part;
5787    if (l) *l = ep->items[index]->padding.l;
5788    if (t) *t = ep->items[index]->padding.t;
5789    if (r) *r = ep->items[index]->padding.r;
5790    if (b) *b = ep->items[index]->padding.b;
5791 
5792    return EINA_TRUE;
5793 }
5794 
5795 EAPI Eina_Bool
edje_edit_part_item_index_padding_set(Evas_Object * obj,const char * part,unsigned int index,int l,int r,int t,int b)5796 edje_edit_part_item_index_padding_set(Evas_Object *obj, const char *part, unsigned int index, int l, int r, int t, int b)
5797 {
5798    Edje_Part *ep;
5799 
5800    if ((!obj) || (!part))
5801      return EINA_FALSE;
5802 
5803    GET_RP_OR_RETURN(EINA_FALSE);
5804 
5805    ep = rp->part;
5806    if (l > -1) ep->items[index]->padding.l = l;
5807    else return EINA_FALSE;
5808    if (t > -1) ep->items[index]->padding.t = t;
5809    else return EINA_FALSE;
5810    if (r > -1) ep->items[index]->padding.r = r;
5811    else return EINA_FALSE;
5812    if (b > -1) ep->items[index]->padding.b = b;
5813    else return EINA_FALSE;
5814 
5815    return EINA_TRUE;
5816 }
5817 
5818 /* deprecated */
5819 #define FUNC_PART_ITEM_DOUBLE(Name, Value, Min, Max)                                                     \
5820   EAPI double                                                                                            \
5821   edje_edit_part_item_##Name##_get(Evas_Object * obj, const char *part, const char *item_name)           \
5822   {                                                                                                      \
5823      Edje_Part *ep;                                                                                      \
5824      unsigned int i;                                                                                     \
5825      Edje_Pack_Element *item = NULL;                                                                     \
5826      if ((!obj) || (!part) || (!item_name))                                                              \
5827        return 0.0;                                                                                       \
5828      GET_RP_OR_RETURN(0.0);                                                                              \
5829      ep = rp->part;                                                                                      \
5830      for (i = 0; i < ep->items_count; ++i)                                                               \
5831        {                                                                                                 \
5832           if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))                            \
5833             {                                                                                            \
5834                item = ep->items[i];                                                                      \
5835                break;                                                                                    \
5836             }                                                                                            \
5837        }                                                                                                 \
5838      if (!item) return EINA_FALSE;                                                                       \
5839      return TO_DOUBLE(item->Value);                                                                      \
5840   }                                                                                                      \
5841   EAPI Eina_Bool                                                                                         \
5842   edje_edit_part_item_##Name##_set(Evas_Object * obj, const char *part, const char *item_name, double v) \
5843   {                                                                                                      \
5844      Edje_Part *ep;                                                                                      \
5845      unsigned int i;                                                                                     \
5846      Edje_Pack_Element *item = NULL;                                                                     \
5847      if ((!obj) || (!part) || (!item_name))                                                              \
5848        return EINA_FALSE;                                                                                \
5849      if ((v < Min) || (v > Max))                                                                         \
5850        return EINA_FALSE;                                                                                \
5851      GET_RP_OR_RETURN(EINA_FALSE);                                                                       \
5852      ep = rp->part;                                                                                      \
5853      if ((rp->part->type != EDJE_PART_TYPE_BOX) &&                                                       \
5854          (rp->part->type != EDJE_PART_TYPE_TABLE))                                                       \
5855        return EINA_FALSE;                                                                                \
5856      for (i = 0; i < ep->items_count; ++i)                                                               \
5857        {                                                                                                 \
5858           if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))                            \
5859             {                                                                                            \
5860                item = ep->items[i];                                                                      \
5861                break;                                                                                    \
5862             }                                                                                            \
5863        }                                                                                                 \
5864      if (!item) return EINA_FALSE;                                                                       \
5865      item->Value = FROM_DOUBLE(v);                                                                       \
5866      return EINA_TRUE;                                                                                   \
5867   }
5868 
5869 FUNC_PART_ITEM_DOUBLE(align_x, align.x, -1.0, 1.0);
5870 FUNC_PART_ITEM_DOUBLE(align_y, align.y, -1.0, 1.0);
5871 FUNC_PART_ITEM_DOUBLE(weight_x, weight.x, 0.0, 99999.990);
5872 FUNC_PART_ITEM_DOUBLE(weight_y, weight.y, 0.0, 99999.990);
5873 
5874 #undef FUNC_PART_ITEM_DOUBLE
5875 
5876 #define FUNC_PART_ITEM_INDEX_DOUBLE(Name, Value, Min, Max)                                                  \
5877   EAPI double                                                                                               \
5878   edje_edit_part_item_index_##Name##_get(Evas_Object * obj, const char *part, unsigned int index)           \
5879   {                                                                                                         \
5880      Edje_Part *ep;                                                                                         \
5881      if ((!obj) || (!part))                                                                                 \
5882        return 0.0;                                                                                          \
5883      GET_RP_OR_RETURN(0.0);                                                                                 \
5884      ep = rp->part;                                                                                         \
5885      return TO_DOUBLE(ep->items[index]->Value);                                                             \
5886   }                                                                                                         \
5887   EAPI Eina_Bool                                                                                            \
5888   edje_edit_part_item_index_##Name##_set(Evas_Object * obj, const char *part, unsigned int index, double v) \
5889   {                                                                                                         \
5890      Edje_Part *ep;                                                                                         \
5891      if ((!obj) || (!part))                                                                                 \
5892        return EINA_FALSE;                                                                                   \
5893      if ((v < Min) || (v > Max))                                                                            \
5894        return EINA_FALSE;                                                                                   \
5895      GET_RP_OR_RETURN(EINA_FALSE);                                                                          \
5896      ep = rp->part;                                                                                         \
5897      if ((rp->part->type != EDJE_PART_TYPE_BOX) &&                                                          \
5898          (rp->part->type != EDJE_PART_TYPE_TABLE))                                                          \
5899        return EINA_FALSE;                                                                                   \
5900      ep->items[index]->Value = FROM_DOUBLE(v);                                                              \
5901      return EINA_TRUE;                                                                                      \
5902   }
5903 
5904 FUNC_PART_ITEM_INDEX_DOUBLE(align_x, align.x, -1.0, 1.0);
5905 FUNC_PART_ITEM_INDEX_DOUBLE(align_y, align.y, -1.0, 1.0);
5906 FUNC_PART_ITEM_INDEX_DOUBLE(weight_x, weight.x, 0.0, 99999.990);
5907 FUNC_PART_ITEM_INDEX_DOUBLE(weight_y, weight.y, 0.0, 99999.990);
5908 
5909 #undef FUNC_PART_ITEM_INDEX_DOUBLE
5910 
5911 /* deprecated */
5912 EAPI Eina_Bool
edje_edit_part_item_position_get(Evas_Object * obj,const char * part,const char * item_name,unsigned short * col,unsigned short * row)5913 edje_edit_part_item_position_get(Evas_Object *obj, const char *part, const char *item_name, unsigned short *col, unsigned short *row)
5914 {
5915    Edje_Part *ep;
5916    unsigned int i;
5917    Edje_Pack_Element *item = NULL;
5918    if ((!obj) || (!part) || (!item_name))
5919      return EINA_FALSE;
5920    GET_RP_OR_RETURN(EINA_FALSE);
5921    ep = rp->part;
5922    for (i = 0; i < ep->items_count; ++i)
5923      {
5924         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
5925           {
5926              item = ep->items[i];
5927              break;
5928           }
5929      }
5930    if (!item) return EINA_FALSE;
5931    *col = item->col;
5932    *row = item->row;
5933    return EINA_TRUE;
5934 }
5935 
5936 /* deprecated */
5937 EAPI Eina_Bool
edje_edit_part_item_position_set(Evas_Object * obj,const char * part,const char * item_name,unsigned short col,unsigned short row)5938 edje_edit_part_item_position_set(Evas_Object *obj, const char *part, const char *item_name, unsigned short col, unsigned short row)
5939 {
5940    Edje_Part *ep;
5941    unsigned int i;
5942    Edje_Pack_Element *item = NULL;
5943    if ((!obj) || (!part) || (!item_name))
5944      return EINA_FALSE;
5945    GET_RP_OR_RETURN(EINA_FALSE);
5946    ep = rp->part;
5947    if (rp->part->type != EDJE_PART_TYPE_TABLE)
5948      return EINA_FALSE;
5949    for (i = 0; i < ep->items_count; ++i)
5950      {
5951         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name)))
5952           {
5953              item = ep->items[i];
5954              break;
5955           }
5956      }
5957    if (!item) return EINA_FALSE;
5958    item->col = col;
5959    item->row = row;
5960    return EINA_TRUE;
5961 }
5962 
5963 #define FUNC_PART_ITEM_USHORT(CLASS, VALUE) \
5964 EAPI unsigned short \
5965 edje_edit_part_item_##CLASS##_##VALUE##_get(Evas_Object *obj, const char *part, const char *item_name) \
5966 { \
5967    Edje_Part *ep; \
5968    unsigned int i; \
5969    Edje_Pack_Element *item = NULL; \
5970    GET_RP_OR_RETURN(0); \
5971    if (!item_name) return 0; \
5972    ep = rp->part; \
5973    if (rp->part->type != EDJE_PART_TYPE_TABLE) return 0; \
5974    for (i = 0; i < ep->items_count; ++i) \
5975      { \
5976         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name))) \
5977           { \
5978              item = ep->items[i]; \
5979              break; \
5980           } \
5981      } \
5982    if (!item) return 0; \
5983    return item->VALUE; \
5984 } \
5985 EAPI Eina_Bool \
5986 edje_edit_part_item_##CLASS##_##VALUE##_set(Evas_Object *obj, const char *part, const char *item_name, unsigned short new_val) \
5987 { \
5988    Edje_Part *ep; \
5989    unsigned int i; \
5990    Edje_Pack_Element *item = NULL; \
5991    GET_RP_OR_RETURN(EINA_FALSE); \
5992    if (!item_name) return EINA_FALSE; \
5993    ep = rp->part; \
5994    if (rp->part->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE; \
5995    for (i = 0; i < ep->items_count; ++i) \
5996      { \
5997         if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item_name))) \
5998           { \
5999              item = ep->items[i]; \
6000              break; \
6001           } \
6002      } \
6003    if (!item) return EINA_FALSE; \
6004    item->VALUE = new_val; \
6005    return EINA_TRUE; \
6006 }
6007 
FUNC_PART_ITEM_USHORT(position,col)6008 FUNC_PART_ITEM_USHORT(position, col)
6009 FUNC_PART_ITEM_USHORT(position, row)
6010 
6011 #undef FUNC_PART_ITEM_USHORT
6012 
6013 #define FUNC_PART_ITEM_INDEX_USHORT(CLASS, VALUE) \
6014 EAPI unsigned short \
6015 edje_edit_part_item_index_##CLASS##_##VALUE##_get(Evas_Object *obj, const char *part, unsigned int index) \
6016 { \
6017    Edje_Part *ep; \
6018    GET_RP_OR_RETURN(0); \
6019    ep = rp->part; \
6020    if (ep->type != EDJE_PART_TYPE_TABLE) return 0; \
6021    return ep->items[index]->VALUE; \
6022 } \
6023 EAPI Eina_Bool \
6024 edje_edit_part_item_index_##CLASS##_##VALUE##_set(Evas_Object *obj, const char *part, unsigned int index, unsigned short new_val) \
6025 { \
6026    Edje_Part *ep; \
6027    GET_RP_OR_RETURN(EINA_FALSE); \
6028    ep = rp->part; \
6029    if (ep->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE; \
6030    ep->items[index]->VALUE = new_val; \
6031    return EINA_TRUE; \
6032 }
6033 
6034 FUNC_PART_ITEM_INDEX_USHORT(position, col)
6035 FUNC_PART_ITEM_INDEX_USHORT(position, row)
6036 
6037 #undef FUNC_PART_ITEM_INDEX_USHORT
6038 
6039 /* deprecated */
6040 EAPI void
6041 edje_edit_part_item_span_get(Evas_Object *obj, const char *part, const char *item_name, unsigned char *col, unsigned char *row)
6042 {
6043    Edje_Part *ep;
6044    unsigned int i;
6045    Edje_Pack_Element *item = NULL;
6046    if ((!obj) || (!part) || (!item_name))
6047      return;
6048    GET_RP_OR_RETURN();
6049    ep = rp->part;
6050    for (i = 0; i < ep->items_count; ++i)
6051      {
6052         if ((ep->items[i]->name) && (!strcmp(ep->items[i]->name, item_name)))
6053           {
6054              item = ep->items[i];
6055              break;
6056           }
6057      }
6058    if (!item) return;
6059    if (col) *col = item->colspan;
6060    if (row) *row = item->rowspan;
6061    return;
6062 }
6063 
6064 /* deprecated */
6065 EAPI Eina_Bool
edje_edit_part_item_span_set(Evas_Object * obj,const char * part,const char * item_name,unsigned char col,unsigned char row)6066 edje_edit_part_item_span_set(Evas_Object *obj, const char *part, const char *item_name, unsigned char col, unsigned char row)
6067 {
6068    Edje_Part *ep;
6069    unsigned int i;
6070    Edje_Pack_Element *item = NULL;
6071    if ((!obj) || (!part) || (!item_name))
6072      return EINA_FALSE;
6073    GET_RP_OR_RETURN(EINA_FALSE);
6074    ep = rp->part;
6075    if ((rp->part->type != EDJE_PART_TYPE_BOX) &&
6076        (rp->part->type != EDJE_PART_TYPE_TABLE))
6077      return EINA_FALSE;
6078    for (i = 0; i < ep->items_count; i++)
6079      {
6080         if ((ep->items[i]->name) && (!strcmp(ep->items[i]->name, item_name)))
6081           {
6082              item = ep->items[i];
6083              break;
6084           }
6085      }
6086    if (!item) return EINA_FALSE;
6087    item->colspan = col;
6088    item->rowspan = row;
6089    return EINA_TRUE;
6090 }
6091 
6092 #define FUNC_PART_ITEM_USHORT(CLASS, VALUE, MEMBER) \
6093 EAPI unsigned short \
6094 edje_edit_part_item_##CLASS##_##VALUE##_get(Evas_Object *obj, const char *part, const char *item_name) \
6095 { \
6096    Edje_Part *ep; \
6097    unsigned int i; \
6098    Edje_Pack_Element *item = NULL; \
6099    GET_RP_OR_RETURN(0); \
6100    if (!item_name) return 0; \
6101    ep = rp->part; \
6102    if (rp->part->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE; \
6103    for (i = 0; i < ep->items_count; ++i) \
6104      { \
6105         if ((ep->items[i]->name) && (!strcmp(ep->items[i]->name, item_name))) \
6106           { \
6107              item = ep->items[i]; \
6108              break; \
6109           } \
6110      } \
6111    if (!item) return 0; \
6112    return  item->MEMBER; \
6113 } \
6114 EAPI Eina_Bool \
6115 edje_edit_part_item_##CLASS##_##VALUE##_set(Evas_Object *obj, const char *part, const char *item_name, unsigned short new_val) \
6116 { \
6117    Edje_Part *ep; \
6118    unsigned int i; \
6119    Edje_Pack_Element *item = NULL; \
6120    GET_RP_OR_RETURN(EINA_FALSE); \
6121    if (!item_name) return EINA_FALSE; \
6122    ep = rp->part; \
6123    if (rp->part->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE; \
6124    for (i = 0; i < ep->items_count; i++) \
6125      { \
6126         if ((ep->items[i]->name) && (!strcmp(ep->items[i]->name, item_name))) \
6127           { \
6128              item = ep->items[i]; \
6129              break; \
6130           } \
6131      } \
6132    if (!item) return EINA_FALSE; \
6133    item->MEMBER = new_val; \
6134    return EINA_TRUE; \
6135 }
6136 
FUNC_PART_ITEM_USHORT(span,col,colspan)6137 FUNC_PART_ITEM_USHORT(span, col, colspan)
6138 FUNC_PART_ITEM_USHORT(span, row, rowspan)
6139 
6140 #undef FUNC_PART_ITEM_USHORT
6141 
6142 #define FUNC_PART_ITEM_INDEX_USHORT(CLASS, VALUE, MEMBER) \
6143 EAPI unsigned short \
6144 edje_edit_part_item_index_##CLASS##_##VALUE##_get(Evas_Object *obj, const char *part, unsigned int index) \
6145 { \
6146    Edje_Part *ep; \
6147    GET_RP_OR_RETURN(0); \
6148    ep = rp->part; \
6149    if (rp->part->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE; \
6150    return  ep->items[index]->MEMBER; \
6151 } \
6152 EAPI Eina_Bool \
6153 edje_edit_part_item_index_##CLASS##_##VALUE##_set(Evas_Object *obj, const char *part, unsigned int index, unsigned short new_val) \
6154 { \
6155    Edje_Part *ep; \
6156    GET_RP_OR_RETURN(EINA_FALSE); \
6157    ep = rp->part; \
6158    if (rp->part->type != EDJE_PART_TYPE_TABLE) return EINA_FALSE; \
6159    ep->items[index]->MEMBER = new_val; \
6160    return EINA_TRUE; \
6161 }
6162 
6163 FUNC_PART_ITEM_INDEX_USHORT(span, col, colspan)
6164 FUNC_PART_ITEM_INDEX_USHORT(span, row, rowspan)
6165 
6166 #undef FUNC_PART_ITEM_INDEX_USHORT
6167 
6168 /*********************/
6169 /*  PART STATES API  */
6170 /*********************/
6171 EAPI Eina_List *
6172 edje_edit_part_states_list_get(Evas_Object *obj, const char *part)
6173 {
6174    char state_name[PATH_MAX];
6175    Eina_List *states = NULL;
6176    unsigned int i;
6177 
6178    GET_RP_OR_RETURN(NULL);
6179 
6180    //Is there a better place to put this? maybe edje_edit_init() ?
6181    setlocale(LC_NUMERIC, "C");
6182 
6183    states = NULL;
6184 
6185    //append default state
6186    snprintf(state_name, PATH_MAX,
6187             "%s %.2f",
6188             rp->part->default_desc->state.name,
6189             rp->part->default_desc->state.value);
6190    states = eina_list_append(states, eina_stringshare_add(state_name));
6191    //printf("NEW STATE def: %s\n", state->state.name);
6192 
6193    //append other states
6194    for (i = 0; i < rp->part->other.desc_count; ++i)
6195      {
6196         snprintf(state_name, sizeof(state_name),
6197                  "%s %.2f",
6198                  rp->part->other.desc[i]->state.name,
6199                  rp->part->other.desc[i]->state.value);
6200         states = eina_list_append(states, eina_stringshare_add(state_name));
6201         //printf("NEW STATE: %s\n", state_name);
6202      }
6203    return states;
6204 }
6205 
6206 EAPI Eina_Bool
edje_edit_state_name_set(Evas_Object * obj,const char * part,const char * state,double value,const char * new_name,double new_value)6207 edje_edit_state_name_set(Evas_Object *obj, const char *part, const char *state, double value, const char *new_name, double new_value)
6208 {
6209    int part_id;
6210    int i;
6211 
6212    GET_PD_OR_RETURN(EINA_FALSE);
6213    //printf("Set name of state: %s in part: %s [new name: %s]\n",
6214    //     part, state, new_name);
6215 
6216    if (!new_name) return EINA_FALSE;
6217 
6218    /* update programs */
6219    /* update the 'state' field in all programs. update only if program has
6220       a single target */
6221    part_id = _edje_part_id_find(ed, part);
6222    for (i = 0; i < ed->collection->patterns.table_programs_size; i++)
6223      {
6224         Edje_Program *epr = ed->collection->patterns.table_programs[i];
6225 
6226         if (eina_list_count(epr->targets) == 1)
6227           {
6228              Edje_Program_Target *t = eina_list_data_get(epr->targets);
6229 
6230              if (t->id == part_id &&
6231                  !strcmp(epr->state, pd->state.name) &&
6232                  EQ(pd->state.value, epr->value))
6233                {
6234                   _edje_if_string_replace(ed, &epr->state, new_name);
6235                   epr->value = value;
6236                }
6237           }
6238      }
6239 
6240    /* set name */
6241    _edje_if_string_replace(ed, &pd->state.name, new_name);
6242    /* set value */
6243    pd->state.value = new_value;
6244 
6245    return EINA_TRUE;
6246 }
6247 
6248 EAPI Eina_Bool
edje_edit_state_del(Evas_Object * obj,const char * part,const char * state,double value)6249 edje_edit_state_del(Evas_Object *obj, const char *part, const char *state, double value)
6250 {
6251    Edje_Part_Collection_Directory_Entry *ce;
6252    Edje_Part_Description_Common *pd;
6253    unsigned int i;
6254 
6255    GET_EED_OR_RETURN(EINA_FALSE);
6256    GET_RP_OR_RETURN(EINA_FALSE);
6257 
6258    if (!edje_edit_state_exist(obj, part, state, value))
6259      return EINA_FALSE;
6260 
6261    pd = _edje_part_description_find_byname(eed, part, state, value);
6262    if (!pd) return EINA_FALSE;
6263 
6264    /* Don't allow to delete default state, for now at least; */
6265    if (pd == rp->part->default_desc)
6266      return EINA_FALSE;
6267 
6268    /* And if we are deleting the current state, go back to default first */
6269    if (pd == rp->chosen_description)
6270      _edje_part_description_apply(ed, rp, "default", 0.0, NULL, 0.0);
6271 
6272    ce = eina_hash_find(ed->file->collection, ed->group);
6273 
6274    for (i = 0; i < rp->part->other.desc_count; ++i)
6275      if (pd == rp->part->other.desc[i])
6276        {
6277           memmove(rp->part->other.desc + i,
6278                   rp->part->other.desc + i + 1,
6279                   sizeof (Edje_Part_Description_Common *) * (rp->part->other.desc_count - i - 1));
6280           rp->part->other.desc_count--;
6281           break;
6282        }
6283 
6284    _edje_collection_free_part_description_free(rp->part->type, pd, ce, 0);
6285    return EINA_TRUE;
6286 }
6287 
6288 static Edje_Part_Description_Common *
_edje_edit_state_alloc(int type,Edje * ed)6289 _edje_edit_state_alloc(int type, Edje *ed)
6290 {
6291    Edje_Part_Collection_Directory_Entry *ce;
6292    Edje_Part_Description_Common *pd = NULL;
6293 
6294    ce = eina_hash_find(ed->file->collection, ed->group);
6295    if (!ce) return NULL;
6296 
6297    switch (type)
6298      {
6299       case EDJE_PART_TYPE_RECTANGLE:
6300         pd = eina_mempool_malloc(ce->mp->mp.RECTANGLE, sizeof (Edje_Part_Description_Common));
6301         if (!pd) return NULL;
6302         ce->count.RECTANGLE++;
6303         break;
6304 
6305       case EDJE_PART_TYPE_SPACER:
6306         pd = eina_mempool_malloc(ce->mp->mp.SPACER, sizeof (Edje_Part_Description_Common));
6307         if (!pd) return NULL;
6308         ce->count.SPACER++;
6309         break;
6310 
6311       case EDJE_PART_TYPE_SWALLOW:
6312         pd = eina_mempool_malloc(ce->mp->mp.SWALLOW, sizeof (Edje_Part_Description_Common));
6313         if (!pd) return NULL;
6314         ce->count.SWALLOW++;
6315         break;
6316 
6317       case EDJE_PART_TYPE_GROUP:
6318         pd = eina_mempool_malloc(ce->mp->mp.GROUP, sizeof (Edje_Part_Description_Common));
6319         if (!pd) return NULL;
6320         ce->count.GROUP++;
6321         break;
6322 
6323 #define EDIT_ALLOC_POOL(Short, Type, Name)                            \
6324 case EDJE_PART_TYPE_##Short:                                          \
6325 {                                                                     \
6326    Edje_Part_Description_##Type *Name = NULL;                         \
6327                                                                       \
6328    Name = eina_mempool_malloc(ce->mp->mp.Short,                       \
6329                               sizeof (Edje_Part_Description_##Type)); \
6330    if (!Name) return NULL;                                            \
6331    memset(Name, 0, sizeof(Edje_Part_Description_##Type));             \
6332    pd = &Name->common;                                                \
6333    ce->count.Short++;                                                 \
6334    break;                                                             \
6335 }
6336 
6337         EDIT_ALLOC_POOL(IMAGE, Image, image);
6338         EDIT_ALLOC_POOL(PROXY, Proxy, proxy);
6339         EDIT_ALLOC_POOL(TEXT, Text, text);
6340         EDIT_ALLOC_POOL(TEXTBLOCK, Text, text);
6341         EDIT_ALLOC_POOL(BOX, Box, box);
6342         EDIT_ALLOC_POOL(TABLE, Table, table);
6343         EDIT_ALLOC_POOL(EXTERNAL, External, external_params);
6344         EDIT_ALLOC_POOL(VECTOR, Vector, vector);
6345      }
6346 
6347    return pd;
6348 }
6349 
6350 EAPI Eina_Bool
edje_edit_state_add(Evas_Object * obj,const char * part,const char * name,double value)6351 edje_edit_state_add(Evas_Object *obj, const char *part, const char *name, double value)
6352 {
6353    Edje_Part_Description_Common *pd;
6354 
6355    GET_RP_OR_RETURN(EINA_FALSE);
6356 
6357    if (edje_edit_state_exist(obj, part, name, value))
6358      return EINA_FALSE;
6359 
6360    //printf("ADD STATE: %s TO PART: %s\n", name , part);
6361    pd = _edje_edit_state_alloc(rp->part->type, ed);
6362    if (!pd) return EINA_FALSE;
6363 
6364    if (!rp->part->default_desc)
6365      {
6366         rp->part->default_desc = pd;
6367      }
6368    else
6369      {
6370         Edje_Part_Description_Common **tmp;
6371 
6372         tmp = realloc(rp->part->other.desc,
6373                       sizeof (Edje_Part_Description_Common *) * (rp->part->other.desc_count + 1));
6374         if (!tmp)
6375           {
6376              free(pd);
6377              return EINA_FALSE;
6378           }
6379         rp->part->other.desc = tmp;
6380         rp->part->other.desc[rp->part->other.desc_count++] = pd;
6381      }
6382 
6383    memset(pd, 0, sizeof (*pd));
6384 
6385    pd->state.name = eina_stringshare_add(name);
6386    pd->state.value = value;
6387    pd->visible = 1;
6388    pd->align.x = 0.5;
6389    pd->align.y = 0.5;
6390    pd->min.w = 0;
6391    pd->min.h = 0;
6392    pd->fixed.w = 0;
6393    pd->fixed.h = 0;
6394    pd->max.w = -1;
6395    pd->max.h = -1;
6396    pd->rel1.relative_x = 0.0;
6397    pd->rel1.relative_y = 0.0;
6398    pd->rel1.offset_x = 0;
6399    pd->rel1.offset_y = 0;
6400    pd->rel1.id_x = -1;
6401    pd->rel1.id_y = -1;
6402    pd->rel2.relative_x = 1.0;
6403    pd->rel2.relative_y = 1.0;
6404    pd->rel2.offset_x = -1;
6405    pd->rel2.offset_y = -1;
6406    pd->rel2.id_x = -1;
6407    pd->rel2.id_y = -1;
6408    pd->clip_to_id = -1;
6409    pd->color_class = NULL;
6410    pd->color.r = 255;
6411    pd->color.g = 255;
6412    pd->color.b = 255;
6413    pd->color.a = 255;
6414    pd->color2.r = 0;
6415    pd->color2.g = 0;
6416    pd->color2.b = 0;
6417    pd->color2.a = 255;
6418    pd->map.id_persp = -1;
6419    pd->map.id_light = -1;
6420    pd->map.rot.id_center = -1;
6421    pd->map.rot.x = FROM_DOUBLE(0.0);
6422    pd->map.rot.y = FROM_DOUBLE(0.0);
6423    pd->map.rot.z = FROM_DOUBLE(0.0);
6424    pd->map.colors = NULL;
6425    pd->map.on = EINA_FALSE;
6426    pd->map.smooth = EINA_TRUE;
6427    pd->map.alpha = EINA_TRUE;
6428    pd->map.backcull = EINA_FALSE;
6429    pd->map.persp_on = EINA_FALSE;
6430    pd->persp.zplane = EINA_FALSE;
6431    pd->map.zoom.x = FROM_DOUBLE(1.0);
6432    pd->map.zoom.y = FROM_DOUBLE(1.0);
6433    pd->persp.focal = 1000;
6434 
6435    if (rp->part->type == EDJE_PART_TYPE_TEXT
6436        || rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
6437      {
6438         Edje_Part_Description_Text *text;
6439 
6440         text = (Edje_Part_Description_Text *)pd;
6441 
6442         memset(&text->text, 0, sizeof (text->text));
6443 
6444         text->text.color3.r = 0;
6445         text->text.color3.g = 0;
6446         text->text.color3.b = 0;
6447         text->text.color3.a = 128;
6448         text->text.align.x = 0.5;
6449         text->text.align.y = 0.5;
6450         text->text.id_source = -1;
6451         text->text.id_text_source = -1;
6452      }
6453    else if (rp->part->type == EDJE_PART_TYPE_IMAGE)
6454      {
6455         Edje_Part_Description_Image *img;
6456 
6457         img = (Edje_Part_Description_Image *)pd;
6458 
6459         memset(&img->image, 0, sizeof (img->image));
6460 
6461         img->image.id = -1;
6462         img->image.fill.smooth = 1;
6463         img->image.fill.pos_rel_x = 0.0;
6464         img->image.fill.pos_abs_x = 0;
6465         img->image.fill.rel_x = 1.0;
6466         img->image.fill.abs_x = 0;
6467         img->image.fill.pos_rel_y = 0.0;
6468         img->image.fill.pos_abs_y = 0;
6469         img->image.fill.rel_y = 1.0;
6470         img->image.fill.abs_y = 0;
6471         img->image.fill.type = EDJE_FILL_TYPE_SCALE;
6472      }
6473    else if (rp->part->type == EDJE_PART_TYPE_PROXY)
6474      {
6475         Edje_Part_Description_Proxy *pro;
6476 
6477         pro = (Edje_Part_Description_Proxy *)pd;
6478 
6479         memset(&pro->proxy, 0, sizeof (pro->proxy));
6480 
6481         pro->proxy.id = -1;
6482         pro->proxy.source_visible = EINA_TRUE;
6483         pro->proxy.source_clip = EINA_TRUE;
6484         pro->proxy.fill.smooth = 1;
6485         pro->proxy.fill.pos_rel_x = 0.0;
6486         pro->proxy.fill.pos_abs_x = 0;
6487         pro->proxy.fill.rel_x = 1.0;
6488         pro->proxy.fill.abs_x = 0;
6489         pro->proxy.fill.pos_rel_y = 0.0;
6490         pro->proxy.fill.pos_abs_y = 0;
6491         pro->proxy.fill.rel_y = 1.0;
6492         pro->proxy.fill.abs_y = 0;
6493         pro->proxy.fill.type = EDJE_FILL_TYPE_SCALE;
6494      }
6495    else if (rp->part->type == EDJE_PART_TYPE_EXTERNAL)
6496      {
6497         Edje_Part_Description_External *external;
6498         Edje_External_Param_Info *pi;
6499 
6500         external = (Edje_Part_Description_External *)pd;
6501 
6502         external->external_params = NULL;
6503 
6504         if (rp->part->source)
6505           {
6506              pi = (Edje_External_Param_Info *)edje_external_param_info_get(rp->part->source);
6507              while (pi && pi->name)
6508                {
6509                   Edje_External_Param *p;
6510                   p = _alloc(sizeof(Edje_External_Param));
6511                   /* error checking.. meh */
6512                   p->name = eina_stringshare_add(pi->name);
6513                   p->type = pi->type;
6514                   switch (p->type)
6515                     {
6516                      case EDJE_EXTERNAL_PARAM_TYPE_INT:
6517                      case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
6518                        if (pi->info.i.def != EDJE_EXTERNAL_INT_UNSET)
6519                          p->i = pi->info.i.def;
6520                        break;
6521 
6522                      case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
6523                        if (NEQ(pi->info.d.def, EDJE_EXTERNAL_DOUBLE_UNSET))
6524                          p->d = pi->info.d.def;
6525                        break;
6526 
6527                      case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
6528                        if (pi->info.c.def)
6529                          p->s = eina_stringshare_add(pi->info.c.def);
6530                        break;
6531 
6532                      case EDJE_EXTERNAL_PARAM_TYPE_STRING:
6533                        if (pi->info.s.def)
6534                          p->s = eina_stringshare_add(pi->info.s.def);
6535                        break;
6536 
6537                      default:
6538                        ERR("unknown external parameter type '%d'", p->type);
6539                     }
6540                   external->external_params = eina_list_append(external->external_params, p);
6541                   pi++;
6542                }
6543              if (external->external_params && rp->typedata.swallow)
6544                rp->param1.external_params = _edje_external_params_parse(rp->typedata.swallow->swallowed_object, external->external_params);
6545           }
6546      }
6547    else if (rp->part->type == EDJE_PART_TYPE_BOX)
6548      {
6549         Edje_Part_Description_Box *box;
6550 
6551         box = (Edje_Part_Description_Box *)pd;
6552         memset(&box->box, 0, sizeof (box->box));
6553      }
6554    else if (rp->part->type == EDJE_PART_TYPE_TABLE)
6555      {
6556         Edje_Part_Description_Table *table;
6557 
6558         table = (Edje_Part_Description_Table *)pd;
6559         memset(&table->table, 0, sizeof (table->table));
6560      }
6561 
6562    return EINA_TRUE;
6563 }
6564 
6565 EAPI Eina_Bool
edje_edit_state_exist(Evas_Object * obj,const char * part,const char * state,double value)6566 edje_edit_state_exist(Evas_Object *obj, const char *part, const char *state, double value)
6567 {
6568    GET_PD_OR_RETURN(EINA_FALSE);
6569    return EINA_TRUE;
6570 }
6571 
6572 static Eina_Bool
_edje_edit_part_state_copy(Evas_Object * obj,const char * part,const char * part_to,const char * from,double val_from,const char * to,double val_to)6573 _edje_edit_part_state_copy(Evas_Object *obj, const char *part, const char *part_to, const char *from, double val_from, const char *to, double val_to)
6574 {
6575    Edje_Part_Description_Common *pdfrom, *pdto;
6576    Edje_External_Param *p;
6577    Edje_Real_Part *rpto;
6578 
6579    GET_EED_OR_RETURN(EINA_FALSE);
6580    GET_RP_OR_RETURN(EINA_FALSE);
6581 
6582    pdfrom = _edje_part_description_find_byname(eed, part, from, val_from);
6583    if (!pdfrom)
6584      return EINA_FALSE;
6585 
6586    rpto = _edje_real_part_get(ed, part_to);
6587    if (!rpto)
6588      return EINA_FALSE;
6589    pdto = _edje_part_description_find_byname(eed, part_to, to, val_to);
6590    if (!pdto)
6591      {
6592         Edje_Part_Description_Common **tmp;
6593 
6594         pdto = _edje_edit_state_alloc(rpto->part->type, ed);
6595         if (!pdto) return EINA_FALSE;
6596         /* No need to check for default desc, at this point it must exist */
6597 
6598         tmp = realloc(rpto->part->other.desc,
6599                       sizeof (Edje_Part_Description_Common *) * (rpto->part->other.desc_count + 1));
6600         if (!tmp)
6601           {
6602              free(pdto);
6603              return EINA_FALSE;
6604           }
6605         rpto->part->other.desc = tmp;
6606         rpto->part->other.desc[rpto->part->other.desc_count++] = pdto;
6607      }
6608 
6609 #define PD_STRING_COPY(To, From, _x) \
6610   if (From->_x)                      \
6611     To->_x = (char *)eina_stringshare_add(From->_x);
6612 
6613    /* Copy all value */
6614    *pdto = *pdfrom;
6615    /* Keeping the pdto state name and value */
6616    pdto->state.name = eina_stringshare_add(to);
6617    pdto->state.value = val_to;
6618    /* Update pointer. */
6619    PD_STRING_COPY(pdto, pdfrom, color_class);
6620 
6621    switch (rp->part->type)
6622      {
6623       case EDJE_PART_TYPE_PROXY:
6624       {
6625          Edje_Part_Description_Proxy *pro_to = (Edje_Part_Description_Proxy *)pdto;
6626          Edje_Part_Description_Proxy *pro_from = (Edje_Part_Description_Proxy *)pdfrom;
6627 
6628          pro_to->proxy = pro_from->proxy;
6629 
6630          break;
6631       }
6632 
6633       case EDJE_PART_TYPE_IMAGE:
6634       {
6635          Edje_Part_Description_Image *img_to = (Edje_Part_Description_Image *)pdto;
6636          Edje_Part_Description_Image *img_from = (Edje_Part_Description_Image *)pdfrom;
6637          unsigned int i;
6638 
6639          img_to->image = img_from->image;
6640 
6641          img_to->image.tweens_count = img_from->image.tweens_count;
6642          img_to->image.tweens = calloc(img_to->image.tweens_count,
6643                                        sizeof (Edje_Part_Image_Id *));
6644          if (!img_to->image.tweens)
6645            break;
6646 
6647          for (i = 0; i < img_to->image.tweens_count; ++i)
6648            {
6649               Edje_Part_Image_Id *new_i;
6650               new_i = _alloc(sizeof(Edje_Part_Image_Id));
6651               if (!new_i) continue;
6652 
6653               *new_i = *img_from->image.tweens[i];
6654 
6655               img_to->image.tweens[i] = new_i;
6656            }
6657          break;
6658       }
6659 
6660       case EDJE_PART_TYPE_TEXT:
6661       case EDJE_PART_TYPE_TEXTBLOCK:
6662       {
6663          Edje_Part_Description_Text *text_to = (Edje_Part_Description_Text *)pdto;
6664          Edje_Part_Description_Text *text_from = (Edje_Part_Description_Text *)pdfrom;
6665 
6666          text_to->text = text_from->text;
6667 
6668          /* Update pointers. */
6669          PD_STRING_COPY(text_to, text_from, text.text.str);
6670          PD_STRING_COPY(text_to, text_from, text.text_class);
6671          PD_STRING_COPY(text_to, text_from, text.style.str);
6672          PD_STRING_COPY(text_to, text_from, text.font.str);
6673          PD_STRING_COPY(text_to, text_from, text.repch.str);
6674          break;
6675       }
6676 
6677       case EDJE_PART_TYPE_BOX:
6678       {
6679          Edje_Part_Description_Box *box_to = (Edje_Part_Description_Box *)pdto;
6680          Edje_Part_Description_Box *box_from = (Edje_Part_Description_Box *)pdfrom;
6681 
6682          box_to->box = box_from->box;
6683 
6684          PD_STRING_COPY(box_to, box_from, box.layout);
6685          PD_STRING_COPY(box_to, box_from, box.alt_layout);
6686          break;
6687       }
6688 
6689       case EDJE_PART_TYPE_TABLE:
6690       {
6691          Edje_Part_Description_Table *table_to = (Edje_Part_Description_Table *)pdto;
6692          Edje_Part_Description_Table *table_from = (Edje_Part_Description_Table *)pdfrom;
6693 
6694          table_to->table = table_from->table;
6695          break;
6696       }
6697 
6698       case EDJE_PART_TYPE_EXTERNAL:
6699       {
6700          Edje_Part_Description_External *ext_to = (Edje_Part_Description_External *)pdto;
6701          Edje_Part_Description_External *ext_from = (Edje_Part_Description_External *)pdfrom;
6702          Eina_List *l;
6703 
6704          /* XXX: optimize this, most likely we don't need to remove and add */
6705          EINA_LIST_FREE(ext_to->external_params, p)
6706            {
6707               _edje_if_string_free(ed, &p->name);
6708               if (p->s)
6709                 _edje_if_string_free(ed, &p->s);
6710               free(p);
6711            }
6712          EINA_LIST_FOREACH(ext_from->external_params, l, p)
6713            {
6714               Edje_External_Param *new_p;
6715               new_p = _alloc(sizeof(Edje_External_Param));
6716               new_p->name = eina_stringshare_add(p->name);
6717               new_p->type = p->type;
6718               switch (p->type)
6719                 {
6720                  case EDJE_EXTERNAL_PARAM_TYPE_INT:
6721                    new_p->i = p->i;
6722                    break;
6723 
6724                  case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
6725                    new_p->d = p->d;
6726                    break;
6727 
6728                  case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
6729                  case EDJE_EXTERNAL_PARAM_TYPE_STRING:
6730                    new_p->s = eina_stringshare_add(p->s);
6731                    break;
6732 
6733                  default:
6734                    break;
6735                 }
6736               ext_to->external_params = eina_list_append(ext_to->external_params, new_p);
6737            }
6738          break;
6739       }
6740      }
6741 
6742 #undef PD_STRING_COPY
6743 
6744    return EINA_TRUE;
6745 }
6746 
6747 EAPI Eina_Bool
edje_edit_state_copy(Evas_Object * obj,const char * part,const char * from,double val_from,const char * to,double val_to)6748 edje_edit_state_copy(Evas_Object *obj, const char *part, const char *from, double val_from, const char *to, double val_to)
6749 {
6750    return _edje_edit_part_state_copy(obj, part, part, from, val_from, to, val_to);
6751 }
6752 
6753 #define FUNC_STATE_RELATIVE_DOUBLE(Sub, Value)                                                                                   \
6754   EAPI double                                                                                                                    \
6755   edje_edit_state_##Sub##_relative_##Value##_get(Evas_Object * obj, const char *part, const char *state, double value)           \
6756   {                                                                                                                              \
6757      GET_PD_OR_RETURN(0);                                                                                                        \
6758      return TO_DOUBLE(pd->Sub.relative_##Value);                                                                                 \
6759   }                                                                                                                              \
6760   EAPI Eina_Bool                                                                                                                 \
6761   edje_edit_state_##Sub##_relative_##Value##_set(Evas_Object * obj, const char *part, const char *state, double value, double v) \
6762   {                                                                                                                              \
6763      GET_PD_OR_RETURN(EINA_FALSE);                                                                                               \
6764      pd->Sub.relative_##Value = FROM_DOUBLE(v);                                                                                  \
6765      edje_object_calc_force(obj);                                                                                                \
6766      return EINA_TRUE;                                                                                                           \
6767   }
6768 
6769 FUNC_STATE_RELATIVE_DOUBLE(rel1, x);
6770 FUNC_STATE_RELATIVE_DOUBLE(rel1, y);
6771 FUNC_STATE_RELATIVE_DOUBLE(rel2, x);
6772 FUNC_STATE_RELATIVE_DOUBLE(rel2, y);
6773 
6774 #define FUNC_STATE_OFFSET_INT(Sub, Value)                                                                                   \
6775   EAPI int                                                                                                                  \
6776   edje_edit_state_##Sub##_offset_##Value##_get(Evas_Object * obj, const char *part, const char *state, double value)        \
6777   {                                                                                                                         \
6778      GET_PD_OR_RETURN(0);                                                                                                   \
6779      return pd->Sub.offset_##Value;                                                                                         \
6780   }                                                                                                                         \
6781   EAPI Eina_Bool                                                                                                            \
6782   edje_edit_state_##Sub##_offset_##Value##_set(Evas_Object * obj, const char *part, const char *state, double value, int v) \
6783   {                                                                                                                         \
6784      GET_PD_OR_RETURN(EINA_FALSE);                                                                                          \
6785      pd->Sub.offset_##Value = v;                                                                                            \
6786      edje_object_calc_force(obj);                                                                                           \
6787      return EINA_TRUE;                                                                                                      \
6788   }
6789 
6790 FUNC_STATE_OFFSET_INT(rel1, x);
6791 FUNC_STATE_OFFSET_INT(rel1, y);
6792 FUNC_STATE_OFFSET_INT(rel2, x);
6793 FUNC_STATE_OFFSET_INT(rel2, y);
6794 
6795 #define FUNC_STATE_REL(Sub, Value)                                                                                               \
6796   EAPI const char *                                                                                                              \
6797   edje_edit_state_##Sub##_to_##Value##_get(Evas_Object * obj, const char *part, const char *state, double value)                 \
6798   {                                                                                                                              \
6799      Edje_Real_Part *rel;                                                                                                        \
6800      GET_PD_OR_RETURN(NULL);                                                                                                     \
6801      if (pd->Sub.id_##Value == -1) return NULL;                                                                                  \
6802      rel = ed->table_parts[pd->Sub.id_##Value % ed->table_parts_size];                                                           \
6803      if (rel->part->name) return eina_stringshare_add(rel->part->name);                                                          \
6804      return NULL;                                                                                                                \
6805   }                                                                                                                              \
6806   EAPI Eina_Bool                                                                                                                 \
6807   edje_edit_state_##Sub##_to_##Value##_set(Evas_Object * obj, const char *part, const char *state, double value, const char *to) \
6808   {                                                                                                                              \
6809      Edje_Real_Part *relp;                                                                                                       \
6810      GET_PD_OR_RETURN(EINA_FALSE);                                                                                               \
6811      if ((to) && (strcmp(to, "")))                                                                                               \
6812        {                                                                                                                         \
6813           relp = _edje_real_part_get(ed, to);                                                                                    \
6814           if (!relp) return EINA_FALSE;                                                                                          \
6815           pd->Sub.id_##Value = relp->part->id;                                                                                   \
6816           return EINA_TRUE;                                                                                                      \
6817        }                                                                                                                         \
6818      else                                                                                                                        \
6819        {                                                                                                                         \
6820           pd->Sub.id_##Value = -1;                                                                                               \
6821           return EINA_TRUE;                                                                                                      \
6822        }                                                                                                                         \
6823   }
6824 //note after this call edje_edit_part_selected_state_set() to update !! need to fix this
6825 //_edje_part_description_apply(ed, rp, pd->state.name, pd->state.value, "state", 0.1); //Why segfault??
6826 // edje_object_calc_force(obj);//don't work for redraw
6827 
6828 FUNC_STATE_REL(rel1, x);
6829 FUNC_STATE_REL(rel1, y);
6830 FUNC_STATE_REL(rel2, x);
6831 FUNC_STATE_REL(rel2, y);
6832 
6833 //colors
6834 #define FUNC_COLOR(Code)                                                                                                             \
6835   EAPI void                                                                                                                          \
6836   edje_edit_state_##Code##_get(Evas_Object * obj, const char *part, const char *state, double value, int *r, int *g, int *b, int *a) \
6837   {                                                                                                                                  \
6838      GET_PD_OR_RETURN();                                                                                                             \
6839                                                                                                                                      \
6840      if (r) *r = pd->Code.r;                                                                                                         \
6841      if (g) *g = pd->Code.g;                                                                                                         \
6842      if (b) *b = pd->Code.b;                                                                                                         \
6843      if (a) *a = pd->Code.a;                                                                                                         \
6844   }                                                                                                                                  \
6845   EAPI Eina_Bool                                                                                                                     \
6846   edje_edit_state_##Code##_set(Evas_Object * obj, const char *part, const char *state, double value, int r, int g, int b, int a)     \
6847   {                                                                                                                                  \
6848      if ((!obj) || (!part) || (!state))                                                                                              \
6849        return EINA_FALSE;                                                                                                            \
6850      GET_PD_OR_RETURN(EINA_FALSE);                                                                                                   \
6851                                                                                                                                      \
6852      if (r > -1 && r < 256) pd->Code.r = r;                                                                                          \
6853      else return EINA_FALSE;                                                                                                         \
6854      if (g > -1 && g < 256) pd->Code.g = g;                                                                                          \
6855      else return EINA_FALSE;                                                                                                         \
6856      if (b > -1 && b < 256) pd->Code.b = b;                                                                                          \
6857      else return EINA_FALSE;                                                                                                         \
6858      if (a > -1 && a < 256) pd->Code.a = a;                                                                                          \
6859      else return EINA_FALSE;                                                                                                         \
6860                                                                                                                                      \
6861      edje_object_calc_force(obj);                                                                                                    \
6862      return EINA_TRUE;                                                                                                               \
6863   }
6864 
6865 FUNC_COLOR(color);
6866 FUNC_COLOR(color2);
6867 
6868 EAPI void
edje_edit_state_color3_get(Evas_Object * obj,const char * part,const char * state,double value,int * r,int * g,int * b,int * a)6869 edje_edit_state_color3_get(Evas_Object *obj, const char *part, const char *state, double value, int *r, int *g, int *b, int *a)
6870 {
6871    Edje_Part_Description_Text *txt;
6872 
6873    GET_PD_OR_RETURN();
6874 
6875    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
6876        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
6877      {
6878         if (r) *r = 0;
6879         if (g) *g = 0;
6880         if (b) *b = 0;
6881         if (a) *a = 0;
6882         return;
6883      }
6884 
6885    txt = (Edje_Part_Description_Text *)pd;
6886 
6887    if (r) *r = txt->text.color3.r;
6888    if (g) *g = txt->text.color3.g;
6889    if (b) *b = txt->text.color3.b;
6890    if (a) *a = txt->text.color3.a;
6891 }
6892 
6893 EAPI Eina_Bool
edje_edit_state_color3_set(Evas_Object * obj,const char * part,const char * state,double value,int r,int g,int b,int a)6894 edje_edit_state_color3_set(Evas_Object *obj, const char *part, const char *state, double value, int r, int g, int b, int a)
6895 {
6896    Edje_Part_Description_Text *txt;
6897 
6898    if ((!obj) || (!part) || (!state))
6899      return EINA_FALSE;
6900    GET_PD_OR_RETURN(EINA_FALSE);
6901 
6902    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
6903        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
6904      return EINA_FALSE;
6905 
6906    txt = (Edje_Part_Description_Text *)pd;
6907 
6908    if (r > -1 && r < 256) txt->text.color3.r = r;
6909    else return EINA_FALSE;
6910    if (g > -1 && g < 256) txt->text.color3.g = g;
6911    else return EINA_FALSE;
6912    if (b > -1 && b < 256) txt->text.color3.b = b;
6913    else return EINA_FALSE;
6914    if (a > -1 && a < 256) txt->text.color3.a = a;
6915    else return EINA_FALSE;
6916 
6917    edje_object_calc_force(obj);
6918    return EINA_TRUE;
6919 }
6920 
6921 #define FUNC_STATE_DOUBLE(Class, Value)                                                                                   \
6922   EAPI double                                                                                                             \
6923   edje_edit_state_##Class##_##Value##_get(Evas_Object * obj, const char *part, const char *state, double value)           \
6924   {                                                                                                                       \
6925      GET_PD_OR_RETURN(0);                                                                                                 \
6926      return TO_DOUBLE(pd->Class.Value);                                                                                   \
6927   }                                                                                                                       \
6928   EAPI Eina_Bool                                                                                                          \
6929   edje_edit_state_##Class##_##Value##_set(Evas_Object * obj, const char *part, const char *state, double value, double v) \
6930   {                                                                                                                       \
6931      GET_PD_OR_RETURN(EINA_FALSE);                                                                                        \
6932      pd->Class.Value = FROM_DOUBLE(v);                                                                                    \
6933      edje_object_calc_force(obj);                                                                                         \
6934      return EINA_TRUE;                                                                                                    \
6935   }
6936 
6937 #define FUNC_STATE_INT(Class, Value, Min)                                                                              \
6938   EAPI int                                                                                                             \
6939   edje_edit_state_##Class##_##Value##_get(Evas_Object * obj, const char *part, const char *state, double value)        \
6940   {                                                                                                                    \
6941      GET_PD_OR_RETURN(0);                                                                                              \
6942      return pd->Class.Value;                                                                                           \
6943   }                                                                                                                    \
6944   EAPI Eina_Bool                                                                                                       \
6945   edje_edit_state_##Class##_##Value##_set(Evas_Object * obj, const char *part, const char *state, double value, int v) \
6946   {                                                                                                                    \
6947      if ((!obj) || (!part) || (!state))                                                                                \
6948        return EINA_FALSE;                                                                                              \
6949      if (v < Min) return EINA_FALSE;                                                                                   \
6950      GET_PD_OR_RETURN(EINA_FALSE);                                                                                     \
6951      pd->Class.Value = v;                                                                                              \
6952      edje_object_calc_force(obj);                                                                                      \
6953      return EINA_TRUE;                                                                                                 \
6954   }
6955 
6956 #define FUNC_STATE_BOOL(Class, Value)                                                                                        \
6957   EAPI Eina_Bool                                                                                                             \
6958   edje_edit_state_##Class##_##Value##_get(Evas_Object * obj, const char *part, const char *state, double value)              \
6959   {                                                                                                                          \
6960      GET_PD_OR_RETURN(0);                                                                                                    \
6961      return pd->Class.Value;                                                                                                 \
6962   }                                                                                                                          \
6963   EAPI Eina_Bool                                                                                                             \
6964   edje_edit_state_##Class##_##Value##_set(Evas_Object * obj, const char *part, const char *state, double value, Eina_Bool v) \
6965   {                                                                                                                          \
6966      if ((!obj) || (!part) || (!state))                                                                                      \
6967        return EINA_FALSE;                                                                                                    \
6968      GET_PD_OR_RETURN(EINA_FALSE);                                                                                           \
6969      pd->Class.Value = v;                                                                                                    \
6970      edje_object_calc_force(obj);                                                                                            \
6971      return EINA_TRUE;                                                                                                       \
6972   }
6973 
6974 FUNC_STATE_DOUBLE(align, x);
6975 FUNC_STATE_DOUBLE(align, y);
6976 FUNC_STATE_INT(min, w, 0);
6977 FUNC_STATE_INT(min, h, 0);
6978 FUNC_STATE_INT(max, w, -1);
6979 FUNC_STATE_INT(max, h, -1);
6980 FUNC_STATE_BOOL(fixed, w);
6981 FUNC_STATE_BOOL(fixed, h);
6982 FUNC_STATE_DOUBLE(aspect, min);
6983 FUNC_STATE_DOUBLE(aspect, max);
6984 FUNC_STATE_DOUBLE(minmul, w);
6985 FUNC_STATE_DOUBLE(minmul, h);
6986 
6987 EAPI Eina_Bool
edje_edit_state_size_class_set(Evas_Object * obj,const char * part,const char * state,double value,const char * size_class)6988 edje_edit_state_size_class_set(Evas_Object *obj, const char *part, const char *state, double value, const char *size_class)
6989 {
6990    GET_PD_OR_RETURN(EINA_FALSE);
6991 
6992    _edje_if_string_replace(ed, &pd->size_class, size_class);
6993 
6994    return EINA_TRUE;
6995 }
6996 
6997 EAPI Eina_Bool
edje_edit_state_fill_smooth_get(Evas_Object * obj,const char * part,const char * state,double value)6998 edje_edit_state_fill_smooth_get(Evas_Object *obj, const char *part, const char *state, double value)
6999 {
7000    GET_PD_OR_RETURN(EINA_FALSE)
7001 
7002    switch (rp->part->type)
7003      {
7004       case EDJE_PART_TYPE_IMAGE:
7005       {
7006          Edje_Part_Description_Image *img;
7007          img = (Edje_Part_Description_Image *)pd;
7008          return img->image.fill.smooth;
7009       }
7010 
7011       case EDJE_PART_TYPE_PROXY:
7012       {
7013          Edje_Part_Description_Proxy *pro;
7014          pro = (Edje_Part_Description_Proxy *)pd;
7015          return pro->proxy.fill.smooth;
7016       }
7017      }
7018 
7019    return EINA_FALSE;
7020 }
7021 
7022 EAPI Eina_Bool
edje_edit_state_fill_smooth_set(Evas_Object * obj,const char * part,const char * state,double value,Eina_Bool smooth)7023 edje_edit_state_fill_smooth_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool smooth)
7024 {
7025    GET_PD_OR_RETURN(EINA_FALSE)
7026 
7027    switch (rp->part->type)
7028      {
7029       case EDJE_PART_TYPE_IMAGE:
7030       {
7031          Edje_Part_Description_Image *img;
7032          img = (Edje_Part_Description_Image *)pd;
7033          img->image.fill.smooth = smooth;
7034          return EINA_TRUE;
7035       }
7036 
7037       case EDJE_PART_TYPE_PROXY:
7038       {
7039          Edje_Part_Description_Proxy *pro;
7040          pro = (Edje_Part_Description_Proxy *)pd;
7041          pro->proxy.fill.smooth = smooth;
7042          return EINA_TRUE;
7043       }
7044      }
7045 
7046    return EINA_FALSE;
7047 }
7048 
7049 EAPI Eina_Bool
edje_edit_state_fill_type_set(Evas_Object * obj,const char * part,const char * state,double value,unsigned char fill_type)7050 edje_edit_state_fill_type_set(Evas_Object *obj, const char *part, const char *state, double value, unsigned char fill_type)
7051 {
7052    GET_PD_OR_RETURN(EINA_FALSE)
7053    if (fill_type >= EDJE_FILL_TYPE_LAST)
7054      return EINA_FALSE;
7055 
7056    switch (rp->part->type)
7057      {
7058       case EDJE_PART_TYPE_IMAGE:
7059       {
7060          Edje_Part_Description_Image *img;
7061          img = (Edje_Part_Description_Image *)pd;
7062          img->image.fill.type = fill_type;
7063          return EINA_TRUE;
7064       }
7065 
7066       case EDJE_PART_TYPE_PROXY:
7067       {
7068          Edje_Part_Description_Proxy *pro;
7069          pro = (Edje_Part_Description_Proxy *)pd;
7070          pro->proxy.fill.type = fill_type;
7071          return EINA_TRUE;
7072       }
7073      }
7074 
7075    return EINA_FALSE;
7076 }
7077 
7078 EAPI unsigned char
edje_edit_state_fill_type_get(Evas_Object * obj,const char * part,const char * state,double value)7079 edje_edit_state_fill_type_get(Evas_Object *obj, const char *part, const char *state, double value)
7080 {
7081    GET_PD_OR_RETURN(EDJE_FILL_TYPE_LAST)
7082 
7083    switch (rp->part->type)
7084      {
7085       case EDJE_PART_TYPE_IMAGE:
7086       {
7087          Edje_Part_Description_Image *img;
7088          img = (Edje_Part_Description_Image *)pd;
7089          return img->image.fill.type;
7090       }
7091 
7092       case EDJE_PART_TYPE_PROXY:
7093       {
7094          Edje_Part_Description_Proxy *pro;
7095          pro = (Edje_Part_Description_Proxy *)pd;
7096          return pro->proxy.fill.type;
7097       }
7098      }
7099 
7100    return EDJE_FILL_TYPE_LAST;
7101 }
7102 
7103 #define FUNC_STATE_DOUBLE_FILL(Class, Type, Value)                                                                                     \
7104   EAPI double                                                                                                                          \
7105   edje_edit_state_fill_##Type##_relative_##Value##_get(Evas_Object * obj, const char *part, const char *state, double value)           \
7106   {                                                                                                                                    \
7107      GET_PD_OR_RETURN(0);                                                                                                              \
7108                                                                                                                                        \
7109      switch (rp->part->type)                                                                                                           \
7110        {                                                                                                                               \
7111         case EDJE_PART_TYPE_IMAGE:                                                                                                     \
7112         {                                                                                                                              \
7113            Edje_Part_Description_Image *img;                                                                                           \
7114                                                                                                                                        \
7115            img = (Edje_Part_Description_Image *)pd;                                                                                    \
7116                                                                                                                                        \
7117            return TO_DOUBLE(img->image.fill.Class##rel_##Value);                                                                       \
7118         }                                                                                                                              \
7119         case EDJE_PART_TYPE_PROXY:                                                                                                     \
7120         {                                                                                                                              \
7121            Edje_Part_Description_Proxy *pro;                                                                                           \
7122                                                                                                                                        \
7123            pro = (Edje_Part_Description_Proxy *)pd;                                                                                    \
7124                                                                                                                                        \
7125            return TO_DOUBLE(pro->proxy.fill.Class##rel_##Value);                                                                       \
7126         }                                                                                                                              \
7127        }                                                                                                                               \
7128                                                                                                                                        \
7129      return 0;                                                                                                                         \
7130   }                                                                                                                                    \
7131   EAPI Eina_Bool                                                                                                                       \
7132   edje_edit_state_fill_##Type##_relative_##Value##_set(Evas_Object * obj, const char *part, const char *state, double value, double v) \
7133   {                                                                                                                                    \
7134      GET_PD_OR_RETURN(EINA_FALSE);                                                                                                     \
7135                                                                                                                                        \
7136      switch (rp->part->type)                                                                                                           \
7137        {                                                                                                                               \
7138         case EDJE_PART_TYPE_IMAGE:                                                                                                     \
7139         {                                                                                                                              \
7140            Edje_Part_Description_Image *img;                                                                                           \
7141                                                                                                                                        \
7142            img = (Edje_Part_Description_Image *)pd;                                                                                    \
7143                                                                                                                                        \
7144            img->image.fill.Class##rel_##Value = FROM_DOUBLE(v);                                                                        \
7145                                                                                                                                        \
7146            break;                                                                                                                      \
7147         }                                                                                                                              \
7148         case EDJE_PART_TYPE_PROXY:                                                                                                     \
7149         {                                                                                                                              \
7150            Edje_Part_Description_Proxy *pro;                                                                                           \
7151                                                                                                                                        \
7152            pro = (Edje_Part_Description_Proxy *)pd;                                                                                    \
7153                                                                                                                                        \
7154            pro->proxy.fill.Class##rel_##Value = FROM_DOUBLE(v);                                                                        \
7155                                                                                                                                        \
7156            break;                                                                                                                      \
7157         }                                                                                                                              \
7158         default:                                                                                                                       \
7159           return EINA_FALSE;                                                                                                           \
7160        }                                                                                                                               \
7161                                                                                                                                        \
7162      edje_object_calc_force(obj);                                                                                                      \
7163      return EINA_TRUE;                                                                                                                 \
7164   }
7165 
7166 #define FUNC_STATE_INT_FILL(Class, Type, Value)                                                                                      \
7167   EAPI int                                                                                                                           \
7168   edje_edit_state_fill_##Type##_offset_##Value##_get(Evas_Object * obj, const char *part, const char *state, double value)           \
7169   {                                                                                                                                  \
7170      GET_PD_OR_RETURN(0);                                                                                                            \
7171                                                                                                                                      \
7172      switch (rp->part->type)                                                                                                         \
7173        {                                                                                                                             \
7174         case EDJE_PART_TYPE_IMAGE:                                                                                                   \
7175         {                                                                                                                            \
7176            Edje_Part_Description_Image *img;                                                                                         \
7177                                                                                                                                      \
7178            img = (Edje_Part_Description_Image *)pd;                                                                                  \
7179                                                                                                                                      \
7180            return img->image.fill.Class##abs_##Value;                                                                                \
7181         }                                                                                                                            \
7182         case EDJE_PART_TYPE_PROXY:                                                                                                   \
7183         {                                                                                                                            \
7184            Edje_Part_Description_Proxy *pro;                                                                                         \
7185                                                                                                                                      \
7186            pro = (Edje_Part_Description_Proxy *)pd;                                                                                  \
7187                                                                                                                                      \
7188            return pro->proxy.fill.Class##abs_##Value;                                                                                \
7189         }                                                                                                                            \
7190        }                                                                                                                             \
7191      return 0;                                                                                                                       \
7192   }                                                                                                                                  \
7193   EAPI Eina_Bool                                                                                                                     \
7194   edje_edit_state_fill_##Type##_offset_##Value##_set(Evas_Object * obj, const char *part, const char *state, double value, double v) \
7195   {                                                                                                                                  \
7196      GET_PD_OR_RETURN(EINA_FALSE);                                                                                                   \
7197                                                                                                                                      \
7198      switch (rp->part->type)                                                                                                         \
7199        {                                                                                                                             \
7200         case EDJE_PART_TYPE_IMAGE:                                                                                                   \
7201         {                                                                                                                            \
7202            Edje_Part_Description_Image *img;                                                                                         \
7203                                                                                                                                      \
7204            img = (Edje_Part_Description_Image *)pd;                                                                                  \
7205                                                                                                                                      \
7206            img->image.fill.Class##abs_##Value = FROM_DOUBLE(v);                                                                      \
7207            break;                                                                                                                    \
7208         }                                                                                                                            \
7209         case EDJE_PART_TYPE_PROXY:                                                                                                   \
7210         {                                                                                                                            \
7211            Edje_Part_Description_Proxy *pro;                                                                                         \
7212                                                                                                                                      \
7213            pro = (Edje_Part_Description_Proxy *)pd;                                                                                  \
7214                                                                                                                                      \
7215            pro->proxy.fill.Class##abs_##Value = FROM_DOUBLE(v);                                                                      \
7216            break;                                                                                                                    \
7217         }                                                                                                                            \
7218         default:                                                                                                                     \
7219           return EINA_FALSE;                                                                                                         \
7220        }                                                                                                                             \
7221                                                                                                                                      \
7222      edje_object_calc_force(obj);                                                                                                    \
7223      return EINA_TRUE;                                                                                                               \
7224   }
7225 
7226 FUNC_STATE_DOUBLE_FILL(pos_, origin, x);
7227 FUNC_STATE_DOUBLE_FILL(pos_, origin, y);
7228 FUNC_STATE_INT_FILL(pos_, origin, x);
7229 FUNC_STATE_INT_FILL(pos_, origin, y);
7230 
7231 FUNC_STATE_DOUBLE_FILL(, size, x);
7232 FUNC_STATE_DOUBLE_FILL(, size, y);
7233 FUNC_STATE_INT_FILL(, size, x);
7234 FUNC_STATE_INT_FILL(, size, y);
7235 
7236 EAPI Eina_Bool
edje_edit_state_visible_get(Evas_Object * obj,const char * part,const char * state,double value)7237 edje_edit_state_visible_get(Evas_Object *obj, const char *part, const char *state, double value)
7238 {
7239    GET_PD_OR_RETURN(EINA_FALSE);
7240 
7241    //printf("Get state visible flag of part: %s state: %s\n", part, state);
7242    return pd->visible;
7243 }
7244 
7245 EAPI Eina_Bool
edje_edit_state_visible_set(Evas_Object * obj,const char * part,const char * state,double value,Eina_Bool visible)7246 edje_edit_state_visible_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool visible)
7247 {
7248    if ((!obj) || (!part) || (!state))
7249      return EINA_FALSE;
7250    GET_PD_OR_RETURN(EINA_FALSE);
7251 
7252    if (visible) pd->visible = 1;
7253    else pd->visible = 0;
7254 
7255    edje_object_calc_force(obj);
7256    return EINA_TRUE;
7257 }
7258 
7259 EAPI unsigned char
edje_edit_state_aspect_pref_get(Evas_Object * obj,const char * part,const char * state,double value)7260 edje_edit_state_aspect_pref_get(Evas_Object *obj, const char *part, const char *state, double value)
7261 {
7262    GET_PD_OR_RETURN(0);
7263 
7264    //printf("GET ASPECT_PREF of state '%s' [%d]\n", state, pd->aspect.prefer);
7265    return pd->aspect.prefer;
7266 }
7267 
7268 EAPI Eina_Bool
edje_edit_state_aspect_pref_set(Evas_Object * obj,const char * part,const char * state,double value,unsigned char pref)7269 edje_edit_state_aspect_pref_set(Evas_Object *obj, const char *part, const char *state, double value, unsigned char pref)
7270 {
7271    GET_PD_OR_RETURN(EINA_FALSE);
7272    if (pref > 4) return EINA_FALSE;
7273    pd->aspect.prefer = pref;
7274    edje_object_calc_force(obj);
7275    return EINA_TRUE;
7276 }
7277 
7278 EAPI const char *
edje_edit_state_color_class_get(Evas_Object * obj,const char * part,const char * state,double value)7279 edje_edit_state_color_class_get(Evas_Object *obj, const char *part, const char *state, double value)
7280 {
7281    GET_PD_OR_RETURN(NULL);
7282    //printf("Get ColorClass of part: %s state: %s\n", part, state);
7283    return eina_stringshare_add(pd->color_class);
7284 }
7285 
7286 EAPI Eina_Bool
edje_edit_state_color_class_set(Evas_Object * obj,const char * part,const char * state,double value,const char * color_class)7287 edje_edit_state_color_class_set(Evas_Object *obj, const char *part, const char *state, double value, const char *color_class)
7288 {
7289    Eina_List *l;
7290    Edje_Color_Class *cc;
7291 
7292    if ((!obj) || (!part) || (!state)) return EINA_FALSE;
7293    GET_PD_OR_RETURN(EINA_FALSE);
7294 
7295    if (!color_class)
7296      {
7297         pd->color_class = NULL;
7298         return EINA_TRUE;
7299      }
7300 
7301    if (!ed->file->color_classes) return EINA_FALSE;
7302    EINA_LIST_FOREACH(ed->file->color_classes, l, cc)
7303      {
7304         if (strcmp(cc->name, color_class) == 0)
7305           {
7306              pd->color_class = eina_stringshare_add(color_class);
7307              edje_object_calc_force(obj);
7308              return EINA_TRUE;
7309           }
7310      }
7311    pd->color_class = NULL;
7312    return EINA_FALSE;
7313 }
7314 
7315 EAPI const Eina_List *
edje_edit_state_external_params_list_get(Evas_Object * obj,const char * part,const char * state,double value)7316 edje_edit_state_external_params_list_get(Evas_Object *obj, const char *part, const char *state, double value)
7317 {
7318    Edje_Part_Description_External *external;
7319 
7320    GET_PD_OR_RETURN(NULL);
7321 
7322    if (rp->part->type != EDJE_PART_TYPE_EXTERNAL)
7323      return NULL;
7324 
7325    external = (Edje_Part_Description_External *)pd;
7326 
7327    return external->external_params;
7328 }
7329 
7330 EAPI Eina_Bool
edje_edit_state_external_param_get(Evas_Object * obj,const char * part,const char * state,double value,const char * param,Edje_External_Param_Type * type,void ** val)7331 edje_edit_state_external_param_get(Evas_Object *obj, const char *part, const char *state, double value, const char *param, Edje_External_Param_Type *type, void **val)
7332 {
7333    Edje_Part_Description_External *external;
7334    Edje_External_Param *p;
7335    Eina_List *l;
7336 
7337    GET_PD_OR_RETURN(EINA_FALSE);
7338 
7339    if (rp->part->type != EDJE_PART_TYPE_EXTERNAL)
7340      return EINA_FALSE;
7341 
7342    if (!param)
7343      return EINA_FALSE;
7344 
7345    external = (Edje_Part_Description_External *)pd;
7346 
7347    EINA_LIST_FOREACH(external->external_params, l, p)
7348      if (!strcmp(p->name, param))
7349        {
7350           if (type) *type = p->type;
7351           if (val)
7352             switch (p->type)
7353               {
7354                case EDJE_EXTERNAL_PARAM_TYPE_INT:
7355                case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
7356                  *val = &p->i;
7357                  break;
7358 
7359                case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
7360                  *val = &p->d;
7361                  break;
7362 
7363                case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
7364                case EDJE_EXTERNAL_PARAM_TYPE_STRING:
7365                  *val = (void *)p->s;
7366                  break;
7367 
7368                default:
7369                  ERR("unknown external parameter type '%d'", p->type);
7370               }
7371           return EINA_TRUE;
7372        }
7373 
7374    return EINA_FALSE;
7375 }
7376 
7377 EAPI Eina_Bool
edje_edit_state_external_param_int_get(Evas_Object * obj,const char * part,const char * state,double value,const char * param,int * val)7378 edje_edit_state_external_param_int_get(Evas_Object *obj, const char *part, const char *state, double value, const char *param, int *val)
7379 {
7380    Edje_Part_Description_External *external;
7381    Edje_External_Param *p;
7382    Eina_List *l;
7383 
7384    GET_PD_OR_RETURN(EINA_FALSE);
7385 
7386    if (rp->part->type != EDJE_PART_TYPE_EXTERNAL)
7387      {
7388         if (val) *val = 0;
7389         return EINA_FALSE;
7390      }
7391 
7392    if (!param)
7393      return EINA_FALSE;
7394 
7395    external = (Edje_Part_Description_External *)pd;
7396 
7397    EINA_LIST_FOREACH(external->external_params, l, p)
7398      if (!strcmp(p->name, param))
7399        {
7400           if (p->type != EDJE_EXTERNAL_PARAM_TYPE_INT)
7401             return EINA_FALSE;
7402           if (val)
7403             *val = p->i;
7404           return EINA_TRUE;
7405        }
7406 
7407    return EINA_FALSE;
7408 }
7409 
7410 EAPI Eina_Bool
edje_edit_state_external_param_bool_get(Evas_Object * obj,const char * part,const char * state,double value,const char * param,Eina_Bool * val)7411 edje_edit_state_external_param_bool_get(Evas_Object *obj, const char *part, const char *state, double value, const char *param, Eina_Bool *val)
7412 {
7413    Edje_Part_Description_External *external;
7414    Edje_External_Param *p;
7415    Eina_List *l;
7416 
7417    GET_PD_OR_RETURN(EINA_FALSE);
7418 
7419    if (rp->part->type != EDJE_PART_TYPE_EXTERNAL)
7420      {
7421         if (val) *val = 0;
7422         return EINA_FALSE;
7423      }
7424 
7425    if (!param)
7426      return EINA_FALSE;
7427 
7428    external = (Edje_Part_Description_External *)pd;
7429 
7430    EINA_LIST_FOREACH(external->external_params, l, p)
7431      if (!strcmp(p->name, param))
7432        {
7433           if (p->type != EDJE_EXTERNAL_PARAM_TYPE_BOOL)
7434             return EINA_FALSE;
7435           if (val)
7436             *val = p->i;
7437           return EINA_TRUE;
7438        }
7439 
7440    return EINA_FALSE;
7441 }
7442 
7443 EAPI Eina_Bool
edje_edit_state_external_param_double_get(Evas_Object * obj,const char * part,const char * state,double value,const char * param,double * val)7444 edje_edit_state_external_param_double_get(Evas_Object *obj, const char *part, const char *state, double value, const char *param, double *val)
7445 {
7446    Edje_Part_Description_External *external;
7447    Edje_External_Param *p;
7448    Eina_List *l;
7449 
7450    GET_PD_OR_RETURN(EINA_FALSE);
7451 
7452    if (rp->part->type != EDJE_PART_TYPE_EXTERNAL)
7453      {
7454         if (val) *val = 0;
7455         return EINA_FALSE;
7456      }
7457 
7458    if (!param)
7459      return EINA_FALSE;
7460 
7461    external = (Edje_Part_Description_External *)pd;
7462 
7463    EINA_LIST_FOREACH(external->external_params, l, p)
7464      if (!strcmp(p->name, param))
7465        {
7466           if (p->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE)
7467             return EINA_FALSE;
7468           if (val)
7469             *val = p->d;
7470           return EINA_TRUE;
7471        }
7472 
7473    return EINA_FALSE;
7474 }
7475 
7476 EAPI Eina_Bool
edje_edit_state_external_param_string_get(Evas_Object * obj,const char * part,const char * state,double value,const char * param,const char ** val)7477 edje_edit_state_external_param_string_get(Evas_Object *obj, const char *part, const char *state, double value, const char *param, const char **val)
7478 {
7479    Edje_Part_Description_External *external;
7480    Edje_External_Param *p;
7481    Eina_List *l;
7482 
7483    GET_PD_OR_RETURN(EINA_FALSE);
7484 
7485    if (rp->part->type != EDJE_PART_TYPE_EXTERNAL)
7486      {
7487         if (val) *val = NULL;
7488         return EINA_FALSE;
7489      }
7490 
7491    if (!param)
7492      return EINA_FALSE;
7493 
7494    external = (Edje_Part_Description_External *)pd;
7495 
7496    EINA_LIST_FOREACH(external->external_params, l, p)
7497      if (!strcmp(p->name, param))
7498        {
7499           if (p->type != EDJE_EXTERNAL_PARAM_TYPE_STRING)
7500             return EINA_FALSE;
7501           if (val)
7502             *val = p->s;
7503           return EINA_TRUE;
7504        }
7505 
7506    return EINA_FALSE;
7507 }
7508 
7509 EAPI Eina_Bool
edje_edit_state_external_param_choice_get(Evas_Object * obj,const char * part,const char * state,double value,const char * param,const char ** val)7510 edje_edit_state_external_param_choice_get(Evas_Object *obj, const char *part, const char *state, double value, const char *param, const char **val)
7511 {
7512    Edje_Part_Description_External *external;
7513    Edje_External_Param *p;
7514    Eina_List *l;
7515 
7516    GET_PD_OR_RETURN(EINA_FALSE);
7517 
7518    if (rp->part->type != EDJE_PART_TYPE_EXTERNAL)
7519      {
7520         if (val) *val = NULL;
7521         return EINA_FALSE;
7522      }
7523 
7524    if (!param)
7525      return EINA_FALSE;
7526 
7527    external = (Edje_Part_Description_External *)pd;
7528 
7529    EINA_LIST_FOREACH(external->external_params, l, p)
7530      if (!strcmp(p->name, param))
7531        {
7532           if (p->type != EDJE_EXTERNAL_PARAM_TYPE_CHOICE)
7533             return EINA_FALSE;
7534           if (val)
7535             *val = p->s;
7536           return EINA_TRUE;
7537        }
7538 
7539    return EINA_FALSE;
7540 }
7541 
7542 EAPI Eina_Bool
edje_edit_state_external_param_set(Evas_Object * obj,const char * part,const char * state,double value,const char * param,Edje_External_Param_Type type,...)7543 edje_edit_state_external_param_set(Evas_Object *obj, const char *part, const char *state, double value, const char *param, Edje_External_Param_Type type, ...)
7544 {
7545    va_list ap;
7546    Eina_List *l;
7547    Edje_Part_Description_External *external;
7548    Edje_External_Param *p = NULL, old_p = { 0, 0, 0, 0, 0 };
7549    int found = 0;
7550 
7551    GET_PD_OR_RETURN(EINA_FALSE);
7552 
7553    if (rp->part->type != EDJE_PART_TYPE_EXTERNAL)
7554      return EINA_FALSE;
7555 
7556    if (!param)
7557      return EINA_FALSE;
7558 
7559    external = (Edje_Part_Description_External *)pd;
7560 
7561    va_start(ap, type);
7562 
7563    EINA_LIST_FOREACH(external->external_params, l, p)
7564      if (!strcmp(p->name, param))
7565        {
7566           found = 1;
7567           old_p = *p;
7568           break;
7569        }
7570 
7571    if (!found)
7572      {
7573         p = _alloc(sizeof(Edje_External_Param));
7574         if (!p)
7575           {
7576              va_end(ap);
7577              return EINA_FALSE;
7578           }
7579         p->name = eina_stringshare_add(param);
7580      }
7581 
7582    p->type = type;
7583    p->i = 0;
7584    p->d = 0;
7585    _edje_if_string_free(ed, &p->s);
7586 
7587    switch (type)
7588      {
7589       case EDJE_EXTERNAL_PARAM_TYPE_INT:
7590       case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
7591         p->i = (int)va_arg(ap, int);
7592         break;
7593 
7594       case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
7595         p->d = (double)va_arg(ap, double);
7596         break;
7597 
7598       case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
7599       case EDJE_EXTERNAL_PARAM_TYPE_STRING:
7600         p->s = eina_stringshare_add((const char *)va_arg(ap, char *));
7601         break;
7602 
7603       default:
7604         ERR("unknown external parameter type '%d'", type);
7605         va_end(ap);
7606         if (!found) free(p);
7607         else *p = old_p;
7608         return EINA_FALSE;
7609      }
7610 
7611    va_end(ap);
7612 
7613    //FIXME:
7614    //For now, we're just setting the value if the state is the selected state.
7615    //This is a conceptual error and is incoherent with the rest of the API!
7616    {
7617       const char *sname;
7618       double svalue;
7619       sname = edje_edit_part_selected_state_get(obj, part, &svalue);
7620       if (!strcmp(state, sname) && EQ(svalue, value))
7621         if (!edje_object_part_external_param_set(obj, part, p))
7622           if ((type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE) ||
7623               (type == EDJE_EXTERNAL_PARAM_TYPE_STRING))
7624             {
7625                _edje_if_string_free(ed, &p->s);
7626                if (!found) free(p);
7627                else *p = old_p;
7628                eina_stringshare_del(sname);
7629                return EINA_FALSE;
7630             }
7631       eina_stringshare_del(sname);
7632    }
7633 
7634    if (!found)
7635      {
7636         external->external_params = eina_list_append(external->external_params, p);
7637      }
7638 
7639    if (rp->typedata.swallow && rp->param1.external_params)
7640      _edje_external_parsed_params_free(rp->typedata.swallow->swallowed_object,
7641                                        rp->param1.external_params);
7642    if (rp->typedata.swallow && external->external_params)
7643      rp->param1.external_params = \
7644        _edje_external_params_parse(rp->typedata.swallow->swallowed_object,
7645                                    external->external_params);
7646 
7647    return EINA_TRUE;
7648 }
7649 
7650 EAPI Eina_Bool
edje_edit_state_external_param_int_set(Evas_Object * obj,const char * part,const char * state,double value,const char * param,int val)7651 edje_edit_state_external_param_int_set(Evas_Object *obj, const char *part, const char *state, double value, const char *param, int val)
7652 {
7653    return edje_edit_state_external_param_set(obj, part, state, value, param, EDJE_EXTERNAL_PARAM_TYPE_INT, val);
7654 }
7655 
7656 EAPI Eina_Bool
edje_edit_state_external_param_bool_set(Evas_Object * obj,const char * part,const char * state,double value,const char * param,Eina_Bool val)7657 edje_edit_state_external_param_bool_set(Evas_Object *obj, const char *part, const char *state, double value, const char *param, Eina_Bool val)
7658 {
7659    return edje_edit_state_external_param_set(obj, part, state, value, param, EDJE_EXTERNAL_PARAM_TYPE_BOOL, (int)val);
7660 }
7661 
7662 EAPI Eina_Bool
edje_edit_state_external_param_double_set(Evas_Object * obj,const char * part,const char * state,double value,const char * param,double val)7663 edje_edit_state_external_param_double_set(Evas_Object *obj, const char *part, const char *state, double value, const char *param, double val)
7664 {
7665    return edje_edit_state_external_param_set(obj, part, state, value, param, EDJE_EXTERNAL_PARAM_TYPE_DOUBLE, val);
7666 }
7667 
7668 EAPI Eina_Bool
edje_edit_state_external_param_string_set(Evas_Object * obj,const char * part,const char * state,double value,const char * param,const char * val)7669 edje_edit_state_external_param_string_set(Evas_Object *obj, const char *part, const char *state, double value, const char *param, const char *val)
7670 {
7671    return edje_edit_state_external_param_set(obj, part, state, value, param, EDJE_EXTERNAL_PARAM_TYPE_STRING, val);
7672 }
7673 
7674 EAPI Eina_Bool
edje_edit_state_external_param_choice_set(Evas_Object * obj,const char * part,const char * state,double value,const char * param,const char * val)7675 edje_edit_state_external_param_choice_set(Evas_Object *obj, const char *part, const char *state, double value, const char *param, const char *val)
7676 {
7677    return edje_edit_state_external_param_set(obj, part, state, value, param, EDJE_EXTERNAL_PARAM_TYPE_CHOICE, val);
7678 }
7679 
7680 EAPI Eina_Bool
edje_edit_state_step_set(Evas_Object * obj,const char * part,const char * state,double value,int step_x,int step_y)7681 edje_edit_state_step_set(Evas_Object *obj, const char *part, const char *state, double value, int step_x, int step_y)
7682 {
7683    GET_PD_OR_RETURN(EINA_FALSE);
7684    pd->step.x = step_x;
7685    pd->step.y = step_y;
7686    return EINA_TRUE;
7687 }
7688 
7689 EAPI Eina_Bool
edje_edit_state_step_get(Evas_Object * obj,const char * part,const char * state,double value,int * step_x,int * step_y)7690 edje_edit_state_step_get(Evas_Object *obj, const char *part, const char *state, double value, int *step_x, int *step_y)
7691 {
7692    GET_PD_OR_RETURN(EINA_FALSE);
7693    if (step_x) *step_x = (int)pd->step.x;
7694    if (step_y) *step_y = (int)pd->step.y;
7695    return EINA_TRUE;
7696 }
7697 
7698 EAPI Eina_Bool
edje_edit_state_limit_set(Evas_Object * obj,const char * part,const char * state,double value,unsigned char limit)7699 edje_edit_state_limit_set(Evas_Object *obj, const char *part, const char *state, double value, unsigned char limit)
7700 {
7701    GET_PD_OR_RETURN(EINA_FALSE);
7702    if (limit >= EDJE_STATE_LIMIT_LAST)
7703      return EINA_FALSE;
7704    pd->limit = limit;
7705    return EINA_TRUE;
7706 }
7707 
7708 EAPI unsigned char
edje_edit_state_limit_get(Evas_Object * obj,const char * part,const char * state,double value)7709 edje_edit_state_limit_get(Evas_Object *obj, const char *part, const char *state, double value)
7710 {
7711    GET_PD_OR_RETURN(EDJE_STATE_LIMIT_LAST);
7712    return pd->limit;
7713 }
7714 
7715 /**************/
7716 /*  MAP API */
7717 /**************/
7718 
7719 EAPI const char *
edje_edit_state_map_light_get(Evas_Object * obj,const char * part,const char * state,double value)7720 edje_edit_state_map_light_get(Evas_Object *obj, const char *part, const char *state, double value)
7721 {
7722    Edje_Real_Part *erl;
7723 
7724    GET_PD_OR_RETURN(NULL);
7725 
7726    if (pd->map.id_light == -1) return NULL;
7727 
7728    erl = ed->table_parts[pd->map.id_light];
7729    if (erl->part->name)
7730      return eina_stringshare_add(erl->part->name);
7731 
7732    return NULL;
7733 }
7734 
7735 EAPI const char *
edje_edit_state_map_rotation_center_get(Evas_Object * obj,const char * part,const char * state,double value)7736 edje_edit_state_map_rotation_center_get(Evas_Object *obj, const char *part, const char *state, double value)
7737 {
7738    Edje_Real_Part *erl;
7739 
7740    GET_PD_OR_RETURN(NULL);
7741 
7742    if (pd->map.rot.id_center == -1) return NULL;
7743 
7744    erl = ed->table_parts[pd->map.rot.id_center];
7745    if (erl->part->name)
7746      return eina_stringshare_add(erl->part->name);
7747 
7748    return NULL;
7749 }
7750 
7751 EAPI Eina_Bool
edje_edit_state_map_backface_cull_get(Evas_Object * obj,const char * part,const char * state,double value)7752 edje_edit_state_map_backface_cull_get(Evas_Object *obj, const char *part, const char *state, double value)
7753 {
7754    GET_PD_OR_RETURN(EINA_FALSE);
7755 
7756    return pd->map.backcull;
7757 }
7758 
7759 EAPI Eina_Bool
edje_edit_state_map_backface_cull_set(Evas_Object * obj,const char * part,const char * state,double value,Eina_Bool bool)7760 edje_edit_state_map_backface_cull_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool bool)
7761 {
7762    GET_PD_OR_RETURN(EINA_FALSE);
7763 
7764    pd->map.backcull = bool;
7765 
7766    edje_object_calc_force(obj);
7767    return EINA_TRUE;
7768 }
7769 
7770 EAPI Eina_Bool
edje_edit_state_map_perspective_on_get(Evas_Object * obj,const char * part,const char * state,double value)7771 edje_edit_state_map_perspective_on_get(Evas_Object *obj, const char *part, const char *state, double value)
7772 {
7773    GET_PD_OR_RETURN(EINA_FALSE);
7774 
7775    return pd->map.persp_on;
7776 }
7777 
7778 EAPI Eina_Bool
edje_edit_state_map_perspective_on_set(Evas_Object * obj,const char * part,const char * state,double value,Eina_Bool bool)7779 edje_edit_state_map_perspective_on_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool bool)
7780 {
7781    GET_PD_OR_RETURN(EINA_FALSE);
7782 
7783    pd->map.persp_on = bool;
7784 
7785    edje_object_calc_force(obj);
7786    return EINA_TRUE;
7787 }
7788 
7789 EAPI Eina_Bool
edje_edit_state_map_alpha_get(Evas_Object * obj,const char * part,const char * state,double value)7790 edje_edit_state_map_alpha_get(Evas_Object *obj, const char *part, const char *state, double value)
7791 {
7792    GET_PD_OR_RETURN(EINA_FALSE);
7793 
7794    return pd->map.alpha;
7795 }
7796 
7797 EAPI Eina_Bool
edje_edit_state_map_alpha_set(Evas_Object * obj,const char * part,const char * state,double value,Eina_Bool bool)7798 edje_edit_state_map_alpha_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool bool)
7799 {
7800    GET_PD_OR_RETURN(EINA_FALSE);
7801 
7802    pd->map.alpha = bool;
7803 
7804    edje_object_calc_force(obj);
7805    return EINA_TRUE;
7806 }
7807 
7808 EAPI Eina_Bool
edje_edit_state_map_smooth_set(Evas_Object * obj,const char * part,const char * state,double value,Eina_Bool bool)7809 edje_edit_state_map_smooth_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool bool)
7810 {
7811    GET_PD_OR_RETURN(EINA_FALSE);
7812 
7813    pd->map.smooth = bool;
7814 
7815    edje_object_calc_force(obj);
7816    return EINA_TRUE;
7817 }
7818 
7819 EAPI Eina_Bool
edje_edit_state_map_smooth_get(Evas_Object * obj,const char * part,const char * state,double value)7820 edje_edit_state_map_smooth_get(Evas_Object *obj, const char *part, const char *state, double value)
7821 {
7822    GET_PD_OR_RETURN(EINA_FALSE);
7823 
7824    return pd->map.smooth;
7825 }
7826 
7827 EAPI Eina_Bool
edje_edit_state_map_rotation_set(Evas_Object * obj,const char * part,const char * state,double value,double x,double y,double z)7828 edje_edit_state_map_rotation_set(Evas_Object *obj, const char *part, const char *state, double value, double x, double y, double z)
7829 {
7830    GET_PD_OR_RETURN(EINA_FALSE);
7831 
7832    pd->map.rot.x = FROM_DOUBLE(x);
7833    pd->map.rot.y = FROM_DOUBLE(y);
7834    pd->map.rot.z = FROM_DOUBLE(z);
7835 
7836    edje_object_calc_force(obj);
7837    return EINA_TRUE;
7838 }
7839 
7840 EAPI Eina_Bool
edje_edit_state_map_rotation_get(Evas_Object * obj,const char * part,const char * state,double value,double * x,double * y,double * z)7841 edje_edit_state_map_rotation_get(Evas_Object *obj, const char *part, const char *state, double value, double *x, double *y, double *z)
7842 {
7843    GET_PD_OR_RETURN(EINA_FALSE);
7844 
7845    if (x) *x = TO_DOUBLE(pd->map.rot.x);
7846    if (y) *y = TO_DOUBLE(pd->map.rot.y);
7847    if (z) *z = TO_DOUBLE(pd->map.rot.z);
7848 
7849    return EINA_TRUE;
7850 }
7851 
7852 EAPI Eina_Bool
edje_edit_state_map_zoom_set(Evas_Object * obj,const char * part,const char * state,double value,double x,double y)7853 edje_edit_state_map_zoom_set(Evas_Object *obj, const char *part, const char *state, double value, double x, double y)
7854 {
7855    GET_PD_OR_RETURN(EINA_FALSE);
7856 
7857    pd->map.zoom.x = FROM_DOUBLE(x);
7858    pd->map.zoom.y = FROM_DOUBLE(y);
7859 
7860    edje_object_calc_force(obj);
7861    return EINA_TRUE;
7862 }
7863 
7864 EAPI Eina_Bool
edje_edit_state_map_zoom_get(Evas_Object * obj,const char * part,const char * state,double value,double * x,double * y)7865 edje_edit_state_map_zoom_get(Evas_Object *obj, const char *part, const char *state, double value, double *x, double *y)
7866 {
7867    GET_PD_OR_RETURN(EINA_FALSE);
7868 
7869    if (x) *x = TO_DOUBLE(pd->map.zoom.x);
7870    if (y) *y = TO_DOUBLE(pd->map.zoom.y);
7871 
7872    return EINA_TRUE;
7873 }
7874 
7875 EAPI Eina_Bool
edje_edit_state_map_perspective_zplane_set(Evas_Object * obj,const char * part,const char * state,double value,int zplane)7876 edje_edit_state_map_perspective_zplane_set(Evas_Object *obj, const char *part, const char *state, double value, int zplane)
7877 {
7878    GET_PD_OR_RETURN(EINA_FALSE);
7879 
7880    pd->persp.zplane = zplane;
7881 
7882    edje_object_calc_force(obj);
7883    return EINA_TRUE;
7884 }
7885 
7886 EAPI int
edje_edit_state_map_perspective_zplane_get(Evas_Object * obj,const char * part,const char * state,double value)7887 edje_edit_state_map_perspective_zplane_get(Evas_Object *obj, const char *part, const char *state, double value)
7888 {
7889    GET_PD_OR_RETURN(EINA_FALSE);
7890 
7891    return pd->persp.zplane;
7892 }
7893 
7894 EAPI Eina_Bool
edje_edit_state_map_perspective_focal_set(Evas_Object * obj,const char * part,const char * state,double value,int focal)7895 edje_edit_state_map_perspective_focal_set(Evas_Object *obj, const char *part, const char *state, double value, int focal)
7896 {
7897    GET_PD_OR_RETURN(EINA_FALSE);
7898 
7899    pd->persp.focal = focal;
7900 
7901    edje_object_calc_force(obj);
7902    return EINA_TRUE;
7903 }
7904 
7905 EAPI int
edje_edit_state_map_perspective_focal_get(Evas_Object * obj,const char * part,const char * state,double value)7906 edje_edit_state_map_perspective_focal_get(Evas_Object *obj, const char *part, const char *state, double value)
7907 {
7908    GET_PD_OR_RETURN(EINA_FALSE);
7909 
7910    return pd->persp.focal;
7911 }
7912 
7913 EAPI Eina_Bool
edje_edit_state_map_light_set(Evas_Object * obj,const char * part,const char * state,double value,const char * source_part)7914 edje_edit_state_map_light_set(Evas_Object *obj, const char *part, const char *state, double value, const char *source_part)
7915 {
7916    int src_id = -1;
7917 
7918    GET_PD_OR_RETURN(EINA_FALSE);
7919 
7920    if (source_part)
7921      src_id = _edje_part_id_find(ed, source_part);
7922 
7923    pd->map.id_light = src_id;
7924 
7925    edje_object_calc_force(obj);
7926    return EINA_TRUE;
7927 }
7928 
7929 EAPI Eina_Bool
edje_edit_state_map_rotation_center_set(Evas_Object * obj,const char * part,const char * state,double value,const char * source_part)7930 edje_edit_state_map_rotation_center_set(Evas_Object *obj, const char *part, const char *state, double value, const char *source_part)
7931 {
7932    int src_id = -1;
7933 
7934    GET_PD_OR_RETURN(EINA_FALSE);
7935 
7936    if (source_part)
7937      src_id = _edje_part_id_find(ed, source_part);
7938 
7939    pd->map.rot.id_center = src_id;
7940 
7941    edje_object_calc_force(obj);
7942    return EINA_TRUE;
7943 }
7944 
7945 EAPI Eina_Bool
edje_edit_state_map_point_color_get(Evas_Object * obj,const char * part,const char * state,double value,int idx,int * r,int * g,int * b,int * a)7946 edje_edit_state_map_point_color_get(Evas_Object *obj, const char *part, const char *state, double value, int idx, int *r, int *g, int *b, int *a)
7947 {
7948    Edje_Map_Color *color = NULL;
7949    unsigned int i;
7950 
7951    if ((!obj) || (!part) || (!state))
7952      return EINA_FALSE;
7953 
7954    GET_PD_OR_RETURN(EINA_FALSE);
7955 
7956    /* check if current color is exists and get it. */
7957    for (i = 0; i < pd->map.colors_count; ++i)
7958      {
7959         if (pd->map.colors[i]->idx == idx)
7960           {
7961              color = pd->map.colors[i];
7962              break;
7963           }
7964      }
7965    if (!color)
7966      {
7967         if (r) *r = 255;
7968         if (g) *g = 255;
7969         if (b) *b = 255;
7970         if (a) *a = 255;
7971      }
7972    else
7973      {
7974         if (r) *r = color->r;
7975         if (g) *g = color->g;
7976         if (b) *b = color->b;
7977         if (a) *a = color->a;
7978      }
7979 
7980    return EINA_TRUE;
7981 }
7982 
7983 EAPI Eina_Bool
edje_edit_state_map_point_color_set(Evas_Object * obj,const char * part,const char * state,double value,int idx,int r,int g,int b,int a)7984 edje_edit_state_map_point_color_set(Evas_Object *obj, const char *part, const char *state, double value, int idx, int r, int g, int b, int a)
7985 {
7986    Edje_Map_Color *color = NULL;
7987    unsigned int i;
7988 
7989    if ((!obj) || (!part) || (!state))
7990      return EINA_FALSE;
7991 
7992    GET_PD_OR_RETURN(EINA_FALSE);
7993 
7994    /* check if current color is exists and get it. */
7995    for (i = 0; i < pd->map.colors_count; ++i)
7996      {
7997         if (pd->map.colors[i]->idx == idx)
7998           {
7999              color = pd->map.colors[i];
8000              break;
8001           }
8002      }
8003 
8004    if (!color)
8005      {
8006         if (!(color = _alloc(sizeof(Edje_Map_Color))))
8007           return EINA_FALSE;
8008 
8009         pd->map.colors_count++;
8010         pd->map.colors =
8011           realloc(pd->map.colors,
8012                   sizeof(Edje_Map_Color *) * pd->map.colors_count);
8013         pd->map.colors[pd->map.colors_count - 1] = color;
8014      }
8015 
8016    color->idx = idx;
8017    if ((r > -1) && (r < 256)) color->r = r;
8018    else return EINA_FALSE;
8019    if ((g > -1) && (g < 256)) color->g = g;
8020    else return EINA_FALSE;
8021    if ((b > -1) && (b < 256)) color->b = b;
8022    else return EINA_FALSE;
8023    if ((a > -1) && (a < 256)) color->a = a;
8024    else return EINA_FALSE;
8025 
8026    return EINA_TRUE;
8027 }
8028 
8029 EAPI const char *
edje_edit_state_map_perspective_get(Evas_Object * obj,const char * part,const char * state,double value)8030 edje_edit_state_map_perspective_get(Evas_Object *obj, const char *part, const char *state, double value)
8031 {
8032    Edje_Real_Part *erl;
8033 
8034    GET_PD_OR_RETURN(NULL);
8035 
8036    if (pd->map.id_persp == -1) return NULL;
8037 
8038    erl = ed->table_parts[pd->map.id_persp];
8039    if (erl->part->name)
8040      return eina_stringshare_add(erl->part->name);
8041 
8042    return NULL;
8043 }
8044 
8045 EAPI Eina_Bool
edje_edit_state_map_perspective_set(Evas_Object * obj,const char * part,const char * state,double value,const char * source_part)8046 edje_edit_state_map_perspective_set(Evas_Object *obj, const char *part, const char *state, double value, const char *source_part)
8047 {
8048    int src_id = -1;
8049 
8050    GET_PD_OR_RETURN(EINA_FALSE);
8051 
8052    if (source_part)
8053      src_id = _edje_part_id_find(ed, source_part);
8054 
8055    pd->map.id_persp = src_id;
8056 
8057    edje_object_calc_force(obj);
8058    return EINA_TRUE;
8059 }
8060 
8061 EAPI Eina_Bool
edje_edit_state_map_on_get(Evas_Object * obj,const char * part,const char * state,double value)8062 edje_edit_state_map_on_get(Evas_Object *obj, const char *part, const char *state, double value)
8063 {
8064    GET_PD_OR_RETURN(EINA_FALSE);
8065 
8066    return pd->map.on;
8067 }
8068 
8069 EAPI Eina_Bool
edje_edit_state_map_on_set(Evas_Object * obj,const char * part,const char * state,double value,Eina_Bool on)8070 edje_edit_state_map_on_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool on)
8071 {
8072    GET_PD_OR_RETURN(EINA_FALSE);
8073 
8074    pd->map.on = on;
8075 
8076    edje_object_calc_force(obj);
8077    return EINA_TRUE;
8078 }
8079 
8080 /*********************/
8081 /*  SIZE CLASSES API */
8082 /*********************/
8083 
8084 EAPI Eina_List *
edje_edit_size_classes_list_get(Evas_Object * obj)8085 edje_edit_size_classes_list_get(Evas_Object *obj)
8086 {
8087    Eina_List *classes = NULL;
8088    Eina_List *l;
8089    Edje_Size_Class *sc;
8090 
8091    GET_ED_OR_RETURN(NULL);
8092 
8093    if (!ed->file || !ed->file->size_classes)
8094      return NULL;
8095    EINA_LIST_FOREACH(ed->file->size_classes, l, sc)
8096      classes = eina_list_append(classes, eina_stringshare_add(sc->name));
8097 
8098    return classes;
8099 }
8100 
8101 EAPI Eina_Bool
edje_edit_size_class_add(Evas_Object * obj,const char * name)8102 edje_edit_size_class_add(Evas_Object *obj, const char *name)
8103 {
8104    Eina_List *l;
8105    Edje_Size_Class *sc, *s;
8106 
8107    GET_ED_OR_RETURN(EINA_FALSE);
8108 
8109    if (!name || !ed->file)
8110      return EINA_FALSE;
8111 
8112    EINA_LIST_FOREACH(ed->file->size_classes, l, sc)
8113      if (strcmp(sc->name, name) == 0)
8114        return EINA_FALSE;
8115 
8116    s = _alloc(sizeof(Edje_Size_Class));
8117    if (!s) return EINA_FALSE;
8118 
8119    s->name = eina_stringshare_add(name);
8120    /* set default values for max */
8121    s->maxw = -1;
8122    s->maxh = -1;
8123 
8124    ed->file->size_classes = eina_list_append(ed->file->size_classes, s);
8125 
8126    return EINA_TRUE;
8127 }
8128 
8129 EAPI Eina_Bool
edje_edit_size_class_del(Evas_Object * obj,const char * name)8130 edje_edit_size_class_del(Evas_Object *obj, const char *name)
8131 {
8132    Eina_List *l;
8133    Edje_Size_Class *sc;
8134 
8135    GET_ED_OR_RETURN(EINA_FALSE);
8136 
8137    if (!name || !ed->file || !ed->file->size_classes)
8138      return EINA_FALSE;
8139 
8140    EINA_LIST_FOREACH(ed->file->size_classes, l, sc)
8141      if (strcmp(sc->name, name) == 0)
8142        {
8143           _edje_if_string_free(ed, &sc->name);
8144           ed->file->size_classes = eina_list_remove(ed->file->size_classes, sc);
8145           free(sc);
8146           return EINA_TRUE;
8147        }
8148    return EINA_FALSE;
8149 }
8150 
8151 EAPI Eina_Bool
edje_edit_size_class_name_set(Evas_Object * obj,const char * name,const char * newname)8152 edje_edit_size_class_name_set(Evas_Object *obj, const char *name, const char *newname)
8153 {
8154    Eina_List *l;
8155    Edje_Size_Class *sc;
8156 
8157    GET_ED_OR_RETURN(EINA_FALSE);
8158 
8159    if (!ed->file || !ed->file->size_classes || !newname)
8160      return EINA_FALSE;
8161 
8162    EINA_LIST_FOREACH(ed->file->size_classes, l, sc)
8163      if (!strcmp(sc->name, name))
8164        {
8165           _edje_if_string_replace(ed, &sc->name, newname);
8166           return EINA_TRUE;
8167        }
8168 
8169    return EINA_FALSE;
8170 }
8171 #define FUNC_SIZE_CLASS(TYPE, VALUE, MIN)                                              \
8172 EAPI Evas_Coord                                                                        \
8173 edje_edit_size_class_##TYPE##_##VALUE##_get(Evas_Object *obj, const char *class_name)  \
8174 {                                                                                      \
8175    Eina_List *l;                                                                       \
8176    Edje_Size_Class *sc;                                                                \
8177                                                                                        \
8178    GET_ED_OR_RETURN(EINA_FALSE);                                                       \
8179                                                                                        \
8180    if (!ed->file || !ed->file->size_classes || !class_name)                            \
8181      return EINA_FALSE;                                                                \
8182                                                                                        \
8183    EINA_LIST_FOREACH(ed->file->size_classes, l, sc)                                    \
8184       if (!strcmp(sc->name, class_name))                                               \
8185         return sc->TYPE##VALUE;                                                        \
8186                                                                                        \
8187    return 0;                                                                           \
8188 }                                                                                      \
8189 EAPI Eina_Bool                                                                         \
8190 edje_edit_size_class_##TYPE##_##VALUE##_set(Evas_Object *obj, const char *class_name, Evas_Coord size)\
8191 {                                                                                      \
8192    Eina_List *l;                                                                       \
8193    Edje_Size_Class *sc;                                                                \
8194                                                                                        \
8195    GET_ED_OR_RETURN(EINA_FALSE);                                                       \
8196                                                                                        \
8197    if (!ed->file || !ed->file->size_classes || !class_name)                            \
8198      return EINA_FALSE;                                                                \
8199    if (size < MIN)                                                                     \
8200      return EINA_FALSE;                                                                \
8201                                                                                        \
8202    EINA_LIST_FOREACH(ed->file->size_classes, l, sc)                                    \
8203      if (!strcmp(sc->name, class_name))                                                \
8204        {                                                                               \
8205           sc->TYPE##VALUE = size;                                                      \
8206           return EINA_TRUE;                                                            \
8207        }                                                                               \
8208    return EINA_FALSE;                                                                  \
8209 }
8210 
8211 FUNC_SIZE_CLASS(min, w, 0)
8212 FUNC_SIZE_CLASS(min, h, 0)
8213 FUNC_SIZE_CLASS(max, w, -1)
8214 FUNC_SIZE_CLASS(max, h, -1)
8215 
8216 /*********************/
8217 /*  TEXT CLASSES API */
8218 /*********************/
8219 
8220 EAPI Eina_List *
edje_edit_text_classes_list_get(Evas_Object * obj)8221 edje_edit_text_classes_list_get(Evas_Object *obj)
8222 {
8223    Eina_List *classes = NULL;
8224    Eina_List *l;
8225    Edje_Text_Class *tc;
8226 
8227    GET_ED_OR_RETURN(NULL);
8228 
8229    if (!ed->file || !ed->file->text_classes)
8230      return NULL;
8231    EINA_LIST_FOREACH(ed->file->text_classes, l, tc)
8232      classes = eina_list_append(classes, eina_stringshare_add(tc->name));
8233 
8234    return classes;
8235 }
8236 
8237 EAPI Eina_Bool
edje_edit_text_class_add(Evas_Object * obj,const char * name)8238 edje_edit_text_class_add(Evas_Object *obj, const char *name)
8239 {
8240    Eina_List *l;
8241    Edje_Text_Class *tc, *t;
8242 
8243    GET_ED_OR_RETURN(EINA_FALSE);
8244 
8245    if (!name || !ed->file)
8246      return EINA_FALSE;
8247 
8248    EINA_LIST_FOREACH(ed->file->text_classes, l, tc)
8249      if (strcmp(tc->name, name) == 0)
8250        return EINA_FALSE;
8251 
8252    t = _alloc(sizeof(Edje_Text_Class));
8253    if (!t) return EINA_FALSE;
8254 
8255    t->name = eina_stringshare_add(name);
8256 
8257    ed->file->text_classes = eina_list_append(ed->file->text_classes, t);
8258 
8259    return EINA_TRUE;
8260 }
8261 
8262 EAPI Eina_Bool
edje_edit_text_class_del(Evas_Object * obj,const char * name)8263 edje_edit_text_class_del(Evas_Object *obj, const char *name)
8264 {
8265    Eina_List *l;
8266    Edje_Text_Class *tc;
8267 
8268    GET_ED_OR_RETURN(EINA_FALSE);
8269 
8270    if (!name || !ed->file || !ed->file->text_classes)
8271      return EINA_FALSE;
8272 
8273    EINA_LIST_FOREACH(ed->file->text_classes, l, tc)
8274      if (strcmp(tc->name, name) == 0)
8275        {
8276           _edje_if_string_free(ed, &tc->name);
8277           _edje_if_string_free(ed, &tc->font);
8278           ed->file->text_classes = eina_list_remove(ed->file->text_classes, tc);
8279           free(tc);
8280           return EINA_TRUE;
8281        }
8282    return EINA_FALSE;
8283 }
8284 
8285 EAPI Eina_Bool
edje_edit_text_class_name_set(Evas_Object * obj,const char * name,const char * newname)8286 edje_edit_text_class_name_set(Evas_Object *obj, const char *name, const char *newname)
8287 {
8288    Eina_List *l;
8289    Edje_Text_Class *tc;
8290 
8291    GET_ED_OR_RETURN(EINA_FALSE);
8292 
8293    if (!ed->file || !ed->file->text_classes)
8294      return EINA_FALSE;
8295 
8296    EINA_LIST_FOREACH(ed->file->text_classes, l, tc)
8297      if (!strcmp(tc->name, name))
8298        {
8299           _edje_if_string_replace(ed, &tc->name, newname);
8300           return EINA_TRUE;
8301        }
8302 
8303    return EINA_FALSE;
8304 }
8305 
8306 EAPI Eina_Stringshare *
edje_edit_text_class_font_get(Evas_Object * obj,const char * class_name)8307 edje_edit_text_class_font_get(Evas_Object *obj, const char *class_name)
8308 {
8309    Eina_List *l;
8310    Edje_Text_Class *tc;
8311 
8312    GET_ED_OR_RETURN(NULL);
8313 
8314    if (!ed->file || !ed->file->text_classes)
8315      return NULL;
8316 
8317    EINA_LIST_FOREACH(ed->file->text_classes, l, tc)
8318       if (!strcmp(tc->name, class_name))
8319         return eina_stringshare_add(tc->font);
8320 
8321    return NULL;
8322 }
8323 
8324 EAPI Eina_Bool
edje_edit_text_class_font_set(Evas_Object * obj,const char * class_name,const char * font)8325 edje_edit_text_class_font_set(Evas_Object *obj, const char *class_name, const char *font)
8326 {
8327    Eina_List *l;
8328    Edje_Text_Class *tc;
8329 
8330    GET_ED_OR_RETURN(EINA_FALSE);
8331 
8332    if (!ed->file || !ed->file->text_classes || !class_name)
8333      return EINA_FALSE;
8334 
8335    EINA_LIST_FOREACH(ed->file->text_classes, l, tc)
8336      if (!strcmp(tc->name, class_name))
8337        {
8338           _edje_if_string_replace(ed, &tc->font, font);
8339           return EINA_TRUE;
8340        }
8341    return EINA_FALSE;
8342 }
8343 
8344 EAPI Evas_Font_Size
edje_edit_text_class_size_get(Evas_Object * obj,const char * class_name)8345 edje_edit_text_class_size_get(Evas_Object *obj, const char *class_name)
8346 {
8347    Eina_List *l;
8348    Edje_Text_Class *tc;
8349 
8350    GET_ED_OR_RETURN(EINA_FALSE);
8351 
8352    if (!ed->file || !ed->file->text_classes)
8353      return EINA_FALSE;
8354 
8355    EINA_LIST_FOREACH(ed->file->text_classes, l, tc)
8356       if (!strcmp(tc->name, class_name))
8357         return tc->size;
8358 
8359    return 0;
8360 }
8361 
8362 EAPI Eina_Bool
edje_edit_text_class_size_set(Evas_Object * obj,const char * class_name,Evas_Font_Size size)8363 edje_edit_text_class_size_set(Evas_Object *obj, const char *class_name, Evas_Font_Size size)
8364 {
8365    Eina_List *l;
8366    Edje_Text_Class *tc;
8367 
8368    GET_ED_OR_RETURN(EINA_FALSE);
8369 
8370    if (!ed->file || !ed->file->text_classes || !class_name)
8371      return EINA_FALSE;
8372    if (size < 0)
8373      return EINA_FALSE;
8374 
8375    EINA_LIST_FOREACH(ed->file->text_classes, l, tc)
8376      if (!strcmp(tc->name, class_name))
8377        {
8378           tc->size = size;
8379           return EINA_TRUE;
8380        }
8381    return EINA_FALSE;
8382 }
8383 
8384 
8385 /**************/
8386 /*  TEXT API */
8387 /**************/
8388 
8389 EAPI const char *
edje_edit_state_text_get(Evas_Object * obj,const char * part,const char * state,double value)8390 edje_edit_state_text_get(Evas_Object *obj, const char *part, const char *state, double value)
8391 {
8392    Edje_Part_Description_Text *txt;
8393 
8394    GET_PD_OR_RETURN(NULL);
8395 
8396    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8397        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8398      return NULL;
8399 
8400    txt = (Edje_Part_Description_Text *)pd;
8401 
8402    return eina_stringshare_add(edje_string_get(&txt->text.text));
8403 }
8404 
8405 EAPI Eina_Bool
edje_edit_state_text_set(Evas_Object * obj,const char * part,const char * state,double value,const char * text)8406 edje_edit_state_text_set(Evas_Object *obj, const char *part, const char *state, double value, const char *text)
8407 {
8408    Edje_Part_Description_Text *txt;
8409    Edje_Real_Part *real;
8410    unsigned short i;
8411 
8412    if (!text)
8413      return EINA_FALSE;
8414    GET_PD_OR_RETURN(EINA_FALSE);
8415 
8416    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8417        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8418      return EINA_FALSE;
8419 
8420    txt = (Edje_Part_Description_Text *)pd;
8421 
8422    _edje_if_string_replace(ed, &txt->text.text.str, text);
8423    txt->text.text.id = 0;
8424 
8425    for (i = 0; i < ed->table_parts_size; i++)
8426      {
8427         real = ed->table_parts[i];
8428         if (((rp->part->type == EDJE_PART_TYPE_TEXT) ||
8429              (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)) &&
8430             (real->typedata.text) && (real->typedata.text->text_source == rp))
8431           {
8432              txt = _edje_real_part_text_text_source_description_get(real, NULL);
8433              _edje_if_string_replace(ed, &txt->text.text.str, text);
8434              txt->text.text.id = 0;
8435           }
8436      }
8437 
8438    edje_object_calc_force(obj);
8439    return EINA_TRUE;
8440 }
8441 
8442 EAPI int
edje_edit_state_text_size_get(Evas_Object * obj,const char * part,const char * state,double value)8443 edje_edit_state_text_size_get(Evas_Object *obj, const char *part, const char *state, double value)
8444 {
8445    Edje_Part_Description_Text *txt;
8446 
8447    GET_PD_OR_RETURN(-1);
8448 
8449    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8450        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8451      return -1;
8452 
8453    txt = (Edje_Part_Description_Text *)pd;
8454 
8455    return txt->text.size;
8456 }
8457 
8458 EAPI Eina_Bool
edje_edit_state_text_size_set(Evas_Object * obj,const char * part,const char * state,double value,int size)8459 edje_edit_state_text_size_set(Evas_Object *obj, const char *part, const char *state, double value, int size)
8460 {
8461    Edje_Part_Description_Text *txt;
8462 
8463    if (size < 0) return EINA_FALSE;
8464    GET_PD_OR_RETURN(EINA_FALSE);
8465 
8466    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8467        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8468      return EINA_FALSE;
8469 
8470    txt = (Edje_Part_Description_Text *)pd;
8471 
8472    txt->text.size = size;
8473 
8474    edje_object_calc_force(obj);
8475    return EINA_TRUE;
8476 }
8477 
8478 #define FUNC_TEXT_DOUBLE(Name, Value, Min)                                                                          \
8479   EAPI double                                                                                                       \
8480   edje_edit_state_text_##Name##_get(Evas_Object * obj, const char *part, const char *state, double value)           \
8481   {                                                                                                                 \
8482      Edje_Part_Description_Text *txt;                                                                               \
8483                                                                                                                     \
8484      GET_PD_OR_RETURN(0);                                                                                           \
8485                                                                                                                     \
8486      if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&                                                                 \
8487          (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))                                                              \
8488        return 0;                                                                                                    \
8489                                                                                                                     \
8490      txt = (Edje_Part_Description_Text *)pd;                                                                        \
8491      return TO_DOUBLE(txt->text.Value);                                                                             \
8492   }                                                                                                                 \
8493   EAPI Eina_Bool                                                                                                    \
8494   edje_edit_state_text_##Name##_set(Evas_Object * obj, const char *part, const char *state, double value, double v) \
8495   {                                                                                                                 \
8496      Edje_Part_Description_Text *txt;                                                                               \
8497      if ((!obj) || (!part) || (!state))                                                                             \
8498        return EINA_FALSE;                                                                                           \
8499      if ((v < Min) || (v > 1.0))                                                                                    \
8500        return EINA_FALSE;                                                                                           \
8501                                                                                                                     \
8502      GET_PD_OR_RETURN(EINA_FALSE);                                                                                  \
8503                                                                                                                     \
8504      if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&                                                                 \
8505          (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))                                                              \
8506        return EINA_FALSE;                                                                                           \
8507                                                                                                                     \
8508      txt = (Edje_Part_Description_Text *)pd;                                                                        \
8509      txt->text.Value = FROM_DOUBLE(v);                                                                              \
8510      edje_object_calc_force(obj);                                                                                   \
8511      return EINA_TRUE;                                                                                              \
8512   }
8513 
8514 FUNC_TEXT_DOUBLE(align_x, align.x, -1.0);
8515 FUNC_TEXT_DOUBLE(align_y, align.y, 0.0);
8516 FUNC_TEXT_DOUBLE(elipsis, ellipsis, -1.0);
8517 
8518 #define FUNC_TEXT_BOOL(Name, Type)                                                                                              \
8519   EAPI Eina_Bool                                                                                                                \
8520   edje_edit_state_text_##Name##_##Type##_get(Evas_Object * obj, const char *part, const char *state, double value)              \
8521   {                                                                                                                             \
8522      Edje_Part_Description_Text *txt;                                                                                           \
8523                                                                                                                                 \
8524      GET_PD_OR_RETURN(EINA_FALSE);                                                                                              \
8525                                                                                                                                 \
8526      if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&                                                                             \
8527          (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))                                                                          \
8528        return EINA_FALSE;                                                                                                       \
8529                                                                                                                                 \
8530      txt = (Edje_Part_Description_Text *)pd;                                                                                    \
8531      return txt->text.Name##_##Type;                                                                                            \
8532   }                                                                                                                             \
8533   EAPI Eina_Bool                                                                                                                \
8534   edje_edit_state_text_##Name##_##Type##_set(Evas_Object * obj, const char *part, const char *state, double value, Eina_Bool v) \
8535   {                                                                                                                             \
8536      Edje_Part_Description_Text *txt;                                                                                           \
8537      if ((!obj) || (!part) || (!state))                                                                                         \
8538        return EINA_FALSE;                                                                                                       \
8539      GET_PD_OR_RETURN(EINA_FALSE);                                                                                              \
8540                                                                                                                                 \
8541      if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&                                                                             \
8542          (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))                                                                          \
8543        return EINA_FALSE;                                                                                                       \
8544                                                                                                                                 \
8545      txt = (Edje_Part_Description_Text *)pd;                                                                                    \
8546      txt->text.Name##_##Type = v ? 1 : 0;                                                                                       \
8547      edje_object_calc_force(obj);                                                                                               \
8548      return EINA_TRUE;                                                                                                          \
8549   }
8550 
8551 FUNC_TEXT_BOOL(fit, x);
8552 FUNC_TEXT_BOOL(fit, y);
8553 FUNC_TEXT_BOOL(min, x);
8554 FUNC_TEXT_BOOL(min, y);
8555 FUNC_TEXT_BOOL(max, x);
8556 FUNC_TEXT_BOOL(max, y);
8557 
8558 EAPI const char *
edje_edit_state_text_style_get(Evas_Object * obj,const char * part,const char * state,double value)8559 edje_edit_state_text_style_get(Evas_Object *obj, const char *part, const char *state, double value)
8560 {
8561    Edje_Part_Description_Text *txt;
8562 
8563    GET_PD_OR_RETURN(NULL);
8564 
8565    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8566        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8567      return NULL;
8568 
8569    txt = (Edje_Part_Description_Text *)pd;
8570    if (txt->text.style.str)
8571      return eina_stringshare_add(txt->text.style.str);
8572    else
8573      return NULL;
8574 }
8575 
8576 EAPI Eina_Bool
edje_edit_state_text_style_set(Evas_Object * obj,const char * part,const char * state,double value,const char * style)8577 edje_edit_state_text_style_set(Evas_Object *obj, const char *part, const char *state, double value, const char *style)
8578 {
8579    Edje_Part_Description_Text *txt;
8580 
8581    GET_PD_OR_RETURN(EINA_FALSE);
8582 
8583    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8584        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8585      return EINA_FALSE;
8586 
8587    txt = (Edje_Part_Description_Text *)pd;
8588    if (style == NULL )
8589      {
8590         _edje_if_string_free(ed, &txt->text.style.str);
8591         txt->text.style.str = NULL;
8592      }
8593    else
8594      {
8595         _edje_if_string_replace(ed, &txt->text.style.str, style);
8596      }
8597 
8598    edje_object_calc_force(obj);
8599    return EINA_TRUE;
8600 }
8601 
8602 EAPI Eina_List *
edje_edit_fonts_list_get(Evas_Object * obj)8603 edje_edit_fonts_list_get(Evas_Object *obj)
8604 {
8605    Eina_Iterator *it;
8606    Eina_List *fonts = NULL;
8607    Edje_Font_Directory_Entry *f;
8608 
8609    GET_ED_OR_RETURN(NULL);
8610 
8611    if (!ed->file || !ed->file->fonts) return NULL;
8612 
8613    it = eina_hash_iterator_data_new(ed->file->fonts);
8614    if (!it) return NULL;
8615 
8616    EINA_ITERATOR_FOREACH(it, f)
8617      fonts = eina_list_append(fonts, eina_stringshare_add(f->entry));
8618 
8619    eina_iterator_free(it);
8620 
8621    return fonts;
8622 }
8623 
8624 EAPI Eina_Bool
edje_edit_font_add(Evas_Object * obj,const char * path,const char * alias)8625 edje_edit_font_add(Evas_Object *obj, const char *path, const char *alias)
8626 {
8627    char entry[PATH_MAX];
8628    const char *new_path;
8629    struct stat st;
8630    Edje_Font_Directory_Entry *fnt;
8631 
8632    GET_ED_OR_RETURN(EINA_FALSE);
8633 
8634    INF("ADD FONT: %s", path);
8635 
8636    if (!path) return EINA_FALSE;
8637    if (stat(path, &st) || !S_ISREG(st.st_mode)) return EINA_FALSE;
8638    if (!ed->file) return EINA_FALSE;
8639    if (!ed->path) return EINA_FALSE;
8640 
8641    /* Alias */
8642    if (alias)
8643      {
8644         new_path = ecore_file_file_get(path);
8645      }
8646    else
8647      {
8648         alias = ecore_file_file_get(path);
8649         new_path = alias;
8650      }
8651    snprintf(entry, sizeof(entry), "edje/fonts/%s", alias);
8652 
8653    /* Initializing a new font hash, if no exist */
8654    if (!ed->file->fonts)
8655      {
8656         ed->file->fonts = eina_hash_string_small_new(NULL);
8657         if (!ed->file->fonts) return EINA_FALSE;
8658      }
8659 
8660    /* Check if exists */
8661    fnt = eina_hash_find(ed->file->fonts, alias);
8662    if (fnt)
8663      return EINA_FALSE;
8664 
8665    /* Create Edje_Font_Directory_Entry */
8666    fnt = _alloc(sizeof(Edje_Font_Directory_Entry));
8667    if (!fnt)
8668      {
8669         ERR("Unable to alloc font entry part \"%s\"", alias);
8670         return EINA_FALSE;
8671      }
8672    fnt->file = eina_stringshare_add(new_path);
8673    fnt->entry = eina_stringshare_add(alias);
8674 
8675    eina_hash_direct_add(ed->file->fonts, fnt->entry, fnt);
8676 
8677    /* Import font */
8678    if (!_edje_edit_file_import(ed, path, entry, 1))
8679      {
8680         eina_hash_del(ed->file->fonts, fnt->entry, fnt);
8681         eina_stringshare_del(fnt->file);
8682         eina_stringshare_del(fnt->entry);
8683         return EINA_FALSE;
8684      }
8685 
8686    return EINA_TRUE;
8687 }
8688 
8689 EAPI Eina_Bool
edje_edit_font_del(Evas_Object * obj,const char * alias)8690 edje_edit_font_del(Evas_Object *obj, const char *alias)
8691 {
8692    Edje_Font_Directory_Entry *fnt;
8693 
8694    GET_ED_OR_RETURN(EINA_FALSE);
8695 
8696    INF("DEL FONT: %s", alias);
8697 
8698    if (!alias) return EINA_FALSE;
8699    if (!ed->file) return EINA_FALSE;
8700    if (!ed->path) return EINA_FALSE;
8701 
8702    fnt = eina_hash_find(ed->file->fonts, alias);
8703    if (!fnt)
8704      {
8705         WRN("Unable to find font entry part \"%s\"", alias);
8706         return EINA_FALSE;
8707      }
8708 
8709    /* Erase font to edje file */
8710    {
8711       char entry[PATH_MAX];
8712       Eet_File *eetf;
8713 
8714       /* open the eet file */
8715       eetf = _edje_edit_eet_open(ed, EET_FILE_MODE_READ_WRITE);
8716       if (!eetf)
8717         return EINA_FALSE;
8718 
8719       snprintf(entry, sizeof(entry), "edje/fonts/%s", alias);
8720 
8721       if (eet_delete(eetf, entry) <= 0)
8722         {
8723            ERR("Unable to delete \"%s\" font entry", entry);
8724            _edje_edit_eet_close(eetf);
8725            return EINA_FALSE;
8726         }
8727 
8728       /* write the edje_file */
8729       if (!_edje_edit_edje_file_save(eetf, ed->file))
8730         {
8731            _edje_edit_eet_close(eetf);
8732            return EINA_FALSE;
8733         }
8734       _edje_edit_eet_close(eetf);
8735    }
8736 
8737    eina_hash_del(ed->file->fonts, alias, fnt);
8738 
8739    return EINA_TRUE;
8740 }
8741 
8742 EAPI const char *
edje_edit_font_path_get(Evas_Object * obj,const char * alias)8743 edje_edit_font_path_get(Evas_Object *obj, const char *alias)
8744 {
8745    Eina_Iterator *it;
8746    Edje_Font_Directory_Entry *f;
8747    const char *str = NULL;
8748 
8749    if (!alias) return NULL;
8750    GET_ED_OR_RETURN(NULL);
8751 
8752    if (!ed->file || !ed->file->fonts) return NULL;
8753 
8754    it = eina_hash_iterator_data_new(ed->file->fonts);
8755    if (!it) return NULL;
8756 
8757    EINA_ITERATOR_FOREACH(it, f)
8758      if (!strcmp(f->entry, alias))
8759        {
8760           str = f->file;
8761           break;
8762        }
8763 
8764    eina_iterator_free(it);
8765    return eina_stringshare_add(str);
8766 }
8767 
8768 EAPI const char *
edje_edit_state_font_get(Evas_Object * obj,const char * part,const char * state,double value)8769 edje_edit_state_font_get(Evas_Object *obj, const char *part, const char *state, double value)
8770 {
8771    Edje_Part_Description_Text *txt;
8772 
8773    GET_PD_OR_RETURN(NULL);
8774 
8775    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8776        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8777      return NULL;
8778 
8779    txt = (Edje_Part_Description_Text *)pd;
8780 
8781    return eina_stringshare_add(edje_string_get(&txt->text.font));
8782 }
8783 
8784 EAPI Eina_Bool
edje_edit_state_font_set(Evas_Object * obj,const char * part,const char * state,double value,const char * font)8785 edje_edit_state_font_set(Evas_Object *obj, const char *part, const char *state, double value, const char *font)
8786 {
8787    Edje_Part_Description_Text *txt;
8788 
8789    GET_PD_OR_RETURN(EINA_FALSE);
8790 
8791    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8792        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8793      return EINA_FALSE;
8794 
8795    txt = (Edje_Part_Description_Text *)pd;
8796 
8797    _edje_if_string_replace(ed, &txt->text.font.str, font);
8798    txt->text.font.id = 0;
8799 
8800    edje_object_calc_force(obj);
8801    return EINA_TRUE;
8802 }
8803 
8804 EAPI Edje_Text_Effect
edje_edit_part_effect_get(Evas_Object * obj,const char * part)8805 edje_edit_part_effect_get(Evas_Object *obj, const char *part)
8806 {
8807    GET_RP_OR_RETURN(0);
8808 
8809    //printf("GET EFFECT of part: %s\n", part);
8810    return rp->part->effect;
8811 }
8812 
8813 EAPI Eina_Bool
edje_edit_part_effect_set(Evas_Object * obj,const char * part,Edje_Text_Effect effect)8814 edje_edit_part_effect_set(Evas_Object *obj, const char *part, Edje_Text_Effect effect)
8815 {
8816    if ((!obj) || (!part)) return EINA_FALSE;
8817    GET_RP_OR_RETURN(EINA_FALSE);
8818 
8819    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8820        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8821      return EINA_FALSE;
8822    rp->part->effect = effect;
8823 
8824    edje_object_calc_force(obj);
8825    return EINA_TRUE;
8826 }
8827 
8828 EAPI const char *
edje_edit_state_text_text_source_get(Evas_Object * obj,const char * part,const char * state,double value)8829 edje_edit_state_text_text_source_get(Evas_Object *obj, const char *part, const char *state, double value)
8830 {
8831    Edje_Real_Part *rel;
8832 
8833    GET_PD_OR_RETURN(NULL);
8834 
8835    if ((rp->part->type == EDJE_PART_TYPE_TEXT) ||
8836        (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK))
8837      {
8838         Edje_Part_Description_Text *txt;
8839         txt = (Edje_Part_Description_Text *)pd;
8840         if (txt->text.id_text_source == -1) return NULL;
8841         rel = ed->table_parts[txt->text.id_text_source % ed->table_parts_size];
8842         if (rel->part->name) return eina_stringshare_add(rel->part->name);
8843      }
8844 
8845    return NULL;
8846 }
8847 
8848 EAPI Eina_Bool
edje_edit_state_text_text_source_set(Evas_Object * obj,const char * part,const char * state,double value,const char * source)8849 edje_edit_state_text_text_source_set(Evas_Object *obj, const char *part, const char *state, double value, const char *source)
8850 {
8851    Edje_Part_Description_Text *txt;
8852    int id_text_source;
8853 
8854    GET_PD_OR_RETURN(EINA_FALSE);
8855 
8856    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8857        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8858      return EINA_FALSE;
8859 
8860    if (source)
8861      {
8862         txt = (Edje_Part_Description_Text *)pd;
8863 
8864         id_text_source = _edje_part_id_find(ed, source);
8865         txt->text.id_text_source = id_text_source;
8866 
8867         txt->text.text.str = eina_stringshare_add(NULL);
8868         txt->text.text.id = 0;
8869      }
8870    else
8871      {
8872         txt = (Edje_Part_Description_Text *)pd;
8873         txt->text.id_text_source = -1;
8874         txt->text.text.str = eina_stringshare_add(NULL);
8875      }
8876 
8877    edje_object_calc_force(obj);
8878    return EINA_TRUE;
8879 }
8880 
8881 EAPI const char *
edje_edit_state_text_source_get(Evas_Object * obj,const char * part,const char * state,double value)8882 edje_edit_state_text_source_get(Evas_Object *obj, const char *part, const char *state, double value)
8883 {
8884    Edje_Real_Part *rel;
8885 
8886    GET_PD_OR_RETURN(NULL);
8887 
8888    if ((rp->part->type == EDJE_PART_TYPE_TEXT) ||
8889        (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK))
8890      {
8891         Edje_Part_Description_Text *txt;
8892         txt = (Edje_Part_Description_Text *)pd;
8893         if (txt->text.id_source == -1) return NULL;
8894         rel = ed->table_parts[txt->text.id_source % ed->table_parts_size];
8895         if (rel->part->name) return eina_stringshare_add(rel->part->name);
8896      }
8897 
8898    return NULL;
8899 }
8900 
8901 EAPI Eina_Bool
edje_edit_state_text_source_set(Evas_Object * obj,const char * part,const char * state,double value,const char * source)8902 edje_edit_state_text_source_set(Evas_Object *obj, const char *part, const char *state, double value, const char *source)
8903 {
8904    Edje_Part_Description_Text *txt;
8905    int id_source;
8906 
8907    GET_PD_OR_RETURN(EINA_FALSE);
8908 
8909    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8910        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8911      return EINA_FALSE;
8912 
8913    if (source)
8914      {
8915         txt = (Edje_Part_Description_Text *)pd;
8916 
8917         id_source = _edje_part_id_find(ed, source);
8918         txt->text.id_source = id_source;
8919      }
8920    else
8921      {
8922         txt = (Edje_Part_Description_Text *)pd;
8923         txt->text.id_source = -1;
8924         txt->text.text.str = eina_stringshare_add(NULL);
8925      }
8926    /* need to recalc, because the source part can has a text */
8927    edje_object_calc_force(obj);
8928    return EINA_TRUE;
8929 }
8930 
8931 EAPI const char *
edje_edit_state_text_class_get(Evas_Object * obj,const char * part,const char * state,double value)8932 edje_edit_state_text_class_get(Evas_Object *obj, const char *part, const char *state, double value)
8933 {
8934    Edje_Part_Description_Text *txt;
8935    GET_PD_OR_RETURN(NULL);
8936 
8937    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8938        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8939      return NULL;
8940    txt = (Edje_Part_Description_Text *)pd;
8941 
8942    return eina_stringshare_add(txt->text.text_class);
8943 }
8944 
8945 EAPI Eina_Bool
edje_edit_state_text_class_set(Evas_Object * obj,const char * part,const char * state,double value,const char * text_class)8946 edje_edit_state_text_class_set(Evas_Object *obj, const char *part, const char *state, double value, const char *text_class)
8947 {
8948    Edje_Part_Description_Text *txt;
8949    GET_PD_OR_RETURN(EINA_FALSE);
8950 
8951    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8952        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8953      return EINA_FALSE;
8954    txt = (Edje_Part_Description_Text *)pd;
8955 
8956    txt->text.text_class = (char *)eina_stringshare_add(text_class);
8957    return EINA_TRUE;
8958 }
8959 
8960 EAPI const char *
edje_edit_state_text_repch_get(Evas_Object * obj,const char * part,const char * state,double value)8961 edje_edit_state_text_repch_get(Evas_Object *obj, const char *part, const char *state, double value)
8962 {
8963    Edje_Part_Description_Text *txt;
8964 
8965    GET_PD_OR_RETURN(NULL);
8966    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8967        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8968      return NULL;
8969 
8970    txt = (Edje_Part_Description_Text *)pd;
8971 
8972    return eina_stringshare_add(edje_string_get(&txt->text.repch));
8973 }
8974 
8975 EAPI Eina_Bool
edje_edit_state_text_repch_set(Evas_Object * obj,const char * part,const char * state,double value,const char * repch)8976 edje_edit_state_text_repch_set(Evas_Object *obj, const char *part, const char *state, double value, const char *repch)
8977 {
8978    Edje_Part_Description_Text *txt;
8979 
8980    if (!repch) return EINA_FALSE;
8981    GET_PD_OR_RETURN(EINA_FALSE);
8982    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
8983        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
8984      return EINA_FALSE;
8985 
8986    txt = (Edje_Part_Description_Text *)pd;
8987    _edje_if_string_replace(ed, &txt->text.repch.str, repch);
8988    txt->text.repch.id = 0;
8989 
8990    edje_object_calc_force(obj);
8991    return EINA_TRUE;
8992 }
8993 
8994 EAPI Eina_Bool
edje_edit_state_text_size_range_min_max_get(Evas_Object * obj,const char * part,const char * state,double value,int * min,int * max)8995 edje_edit_state_text_size_range_min_max_get(Evas_Object *obj, const char *part, const char *state, double value, int *min, int *max)
8996 {
8997    Edje_Part_Description_Text *txt;
8998    GET_PD_OR_RETURN(EINA_FALSE);
8999    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
9000        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
9001      return EINA_FALSE;
9002 
9003    txt = (Edje_Part_Description_Text *)pd;
9004    if (min) *min = txt->text.size_range_min;
9005    if (max) *max = txt->text.size_range_max;
9006 
9007    return EINA_TRUE;
9008 }
9009 
9010 EAPI Eina_Bool
edje_edit_state_text_size_range_min_max_set(Evas_Object * obj,const char * part,const char * state,double value,int min,int max)9011 edje_edit_state_text_size_range_min_max_set(Evas_Object *obj, const char *part, const char *state, double value, int min, int max)
9012 {
9013    Edje_Part_Description_Text *txt;
9014    GET_PD_OR_RETURN(EINA_FALSE);
9015    if ((rp->part->type != EDJE_PART_TYPE_TEXT) &&
9016        (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
9017      return EINA_FALSE;
9018 
9019    txt = (Edje_Part_Description_Text *)pd;
9020    txt->text.size_range_min = min;
9021    txt->text.size_range_max = max;
9022 
9023    edje_object_calc_force(obj);
9024    return EINA_TRUE;
9025 }
9026 
9027 EAPI Eina_Bool
edje_edit_state_proxy_source_set(Evas_Object * obj,const char * part,const char * state,double value,const char * source_name)9028 edje_edit_state_proxy_source_set(Evas_Object *obj, const char *part, const char *state, double value, const char *source_name)
9029 {
9030    GET_PD_OR_RETURN(EINA_FALSE);
9031    if (rp->part->type != EDJE_PART_TYPE_PROXY)
9032      return EINA_FALSE;
9033 
9034    Edje_Part_Description_Proxy *proxy_part = (Edje_Part_Description_Proxy *)pd;
9035 
9036    if (source_name)
9037      {
9038         int source_id = _edje_part_id_find(ed, source_name);
9039         if (source_id < 0)
9040           return EINA_FALSE;
9041         proxy_part->proxy.id = source_id;
9042      }
9043    else proxy_part->proxy.id = -1;
9044 
9045    return EINA_TRUE;
9046 }
9047 
9048 EAPI Eina_Stringshare *
edje_edit_state_proxy_source_get(Evas_Object * obj,const char * part,const char * state,double value)9049 edje_edit_state_proxy_source_get(Evas_Object *obj, const char *part, const char *state, double value)
9050 {
9051    GET_PD_OR_RETURN(NULL);
9052    if (rp->part->type != EDJE_PART_TYPE_PROXY)
9053      return NULL;
9054 
9055    Edje_Part_Description_Proxy *proxy_part = (Edje_Part_Description_Proxy *)pd;
9056    const char *source_name;
9057    source_name = _edje_part_name_find(ed, proxy_part->proxy.id);
9058 
9059    return eina_stringshare_add(source_name);
9060 }
9061 
9062 EAPI Eina_Bool
edje_edit_state_proxy_source_clip_set(Evas_Object * obj,const char * part,const char * state,double value,Eina_Bool clip)9063 edje_edit_state_proxy_source_clip_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool clip)
9064 {
9065    GET_PD_OR_RETURN(EINA_FALSE);
9066    if (rp->part->type != EDJE_PART_TYPE_PROXY)
9067      return EINA_FALSE;
9068 
9069    Edje_Part_Description_Proxy *proxy_part = (Edje_Part_Description_Proxy *)pd;
9070    proxy_part->proxy.source_clip = clip;
9071 
9072    return EINA_TRUE;
9073 }
9074 
9075 EAPI Eina_Bool
edje_edit_state_proxy_source_clip_get(Evas_Object * obj,const char * part,const char * state,double value)9076 edje_edit_state_proxy_source_clip_get(Evas_Object *obj, const char *part, const char *state, double value)
9077 {
9078    GET_PD_OR_RETURN(EINA_FALSE);
9079    if (rp->part->type != EDJE_PART_TYPE_PROXY)
9080      return EINA_FALSE;
9081 
9082    Edje_Part_Description_Proxy *proxy_part = (Edje_Part_Description_Proxy *)pd;
9083 
9084    return proxy_part->proxy.source_clip;
9085 }
9086 
9087 EAPI Eina_Bool
edje_edit_state_proxy_source_visible_set(Evas_Object * obj,const char * part,const char * state,double value,Eina_Bool visibility)9088 edje_edit_state_proxy_source_visible_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool visibility)
9089 {
9090    GET_PD_OR_RETURN(EINA_FALSE);
9091    if (rp->part->type != EDJE_PART_TYPE_PROXY)
9092      return EINA_FALSE;
9093 
9094    Edje_Part_Description_Proxy *proxy_part = (Edje_Part_Description_Proxy *)pd;
9095    proxy_part->proxy.source_visible = visibility;
9096 
9097    return EINA_TRUE;
9098 }
9099 
9100 EAPI Eina_Bool
edje_edit_state_proxy_source_visible_get(Evas_Object * obj,const char * part,const char * state,double value)9101 edje_edit_state_proxy_source_visible_get(Evas_Object *obj, const char *part, const char *state, double value)
9102 {
9103    GET_PD_OR_RETURN(EINA_FALSE);
9104    if (rp->part->type != EDJE_PART_TYPE_PROXY)
9105      return EINA_FALSE;
9106 
9107    Edje_Part_Description_Proxy *proxy_part = (Edje_Part_Description_Proxy *)pd;
9108 
9109    return proxy_part->proxy.source_visible;
9110 }
9111 
9112 /*****************/
9113 /* IMAGE SET API */
9114 /*****************/
9115 
9116 EAPI Eina_Bool
edje_edit_image_set_exists(Evas_Object * obj,const char * image)9117 edje_edit_image_set_exists(Evas_Object *obj, const char *image)
9118 {
9119    Edje_Image_Directory_Set *de;
9120    unsigned int i;
9121 
9122    GET_ED_OR_RETURN(EINA_FALSE);
9123 
9124    if (!ed->file) return EINA_FALSE;
9125    if (!ed->file->image_dir) return EINA_FALSE;
9126 
9127    // Gets the Set Entry
9128    for (i = 0; i < ed->file->image_dir->sets_count; ++i)
9129      {
9130         de = ed->file->image_dir->sets + i;
9131         if (de->name && !strcmp(de->name, image))
9132           return EINA_TRUE;
9133      }
9134 
9135    return EINA_FALSE;
9136 }
9137 
9138 EAPI int
edje_edit_image_set_id_get(Evas_Object * obj,const char * image_name)9139 edje_edit_image_set_id_get(Evas_Object *obj, const char *image_name)
9140 {
9141    GET_EED_OR_RETURN(-1);
9142 
9143    return _edje_set_id_find(eed, image_name);
9144 }
9145 
9146 EAPI Eina_Bool
edje_edit_image_set_rename(Evas_Object * obj,const char * set,const char * new_set)9147 edje_edit_image_set_rename(Evas_Object *obj, const char *set, const char *new_set)
9148 {
9149    Edje_Image_Directory_Set *de = NULL;
9150    unsigned int i;
9151    GET_ED_OR_RETURN(EINA_FALSE);
9152 
9153    if (!new_set) return EINA_FALSE;
9154 
9155    // Check if image set with name 'new_set' already exists
9156    if (edje_edit_image_set_id_get(obj, new_set) >= 0)
9157      return EINA_FALSE;
9158 
9159    for (i = 0; i < ed->file->image_dir->sets_count; ++i)
9160      {
9161         de = ed->file->image_dir->sets + i;
9162         if ((de->name) && (!strcmp(set, de->name)))
9163           break;
9164      }
9165    if (i == ed->file->image_dir->sets_count) return EINA_FALSE;
9166 
9167    de->name = (char *)new_set;
9168 
9169    return EINA_TRUE;
9170 }
9171 
9172 EAPI Eina_List *
edje_edit_image_set_list_get(Evas_Object * obj)9173 edje_edit_image_set_list_get(Evas_Object *obj)
9174 {
9175    Eina_List *sets = NULL;
9176    unsigned int i;
9177 
9178    GET_ED_OR_RETURN(NULL);
9179 
9180    if (!ed->file) return NULL;
9181    if (!ed->file->image_dir) return NULL;
9182 
9183    for (i = 0; i < ed->file->image_dir->sets_count; ++i)
9184      sets = eina_list_append(sets,
9185                              eina_stringshare_add(ed->file->image_dir->sets[i].name));
9186 
9187    return sets;
9188 }
9189 
9190 EAPI Eina_Bool
edje_edit_image_set_add(Evas_Object * obj,const char * name)9191 edje_edit_image_set_add(Evas_Object *obj, const char *name)
9192 {
9193    Edje_Image_Directory_Set *de;
9194    unsigned int i;
9195    int free_id = -1;
9196 
9197    GET_ED_OR_RETURN(EINA_FALSE);
9198 
9199    if (!name) return EINA_FALSE;
9200    if (!ed->file) return EINA_FALSE;
9201 
9202    /* Create Image_Directory if not exist */
9203    if (!ed->file->image_dir)
9204      {
9205         ed->file->image_dir = _alloc(sizeof(Edje_Image_Directory));
9206         if (!ed->file->image_dir) return EINA_FALSE;
9207      }
9208 
9209    /* Loop trough image directory to find if image exist */
9210    for (i = 0; i < ed->file->image_dir->sets_count; ++i)
9211      {
9212         de = ed->file->image_dir->sets + i;
9213 
9214         if (!de->name)
9215           free_id = i;
9216         else if (!strcmp(name, de->name))
9217           return EINA_FALSE;
9218      }
9219 
9220    if (free_id == -1)
9221      {
9222         Edje_Image_Directory_Set *tmp;
9223         unsigned int count;
9224 
9225         count = ed->file->image_dir->sets_count + 1;
9226 
9227         tmp = realloc(ed->file->image_dir->sets,
9228                       sizeof (Edje_Image_Directory_Set) * count);
9229         if (!tmp) return EINA_FALSE;
9230 
9231         ed->file->image_dir->sets = tmp;
9232         free_id = ed->file->image_dir->sets_count;
9233         ed->file->image_dir->sets_count = count;
9234      }
9235 
9236    /* Set Image Entry */
9237    de = ed->file->image_dir->sets + free_id;
9238    de->name = (char *)name;
9239    de->id = free_id;
9240    de->entries = NULL;
9241 
9242    return EINA_TRUE;
9243 }
9244 
9245 EAPI Eina_List *
edje_edit_set_usage_list_get(Evas_Object * obj,const char * name,Eina_Bool first_only)9246 edje_edit_set_usage_list_get(Evas_Object *obj, const char *name, Eina_Bool first_only)
9247 {
9248    Eina_List *result = NULL;
9249    Eina_Iterator *it;
9250    Edje_Part_Collection_Directory_Entry *pce;
9251    Edje_Part_Image_Use *item;
9252    Edje_Part *part;
9253    Edje_Part_Description_Image *part_desc_image;
9254    unsigned int i, j, k;
9255    int set_id;
9256 
9257    GET_ED_OR_RETURN(NULL);
9258 
9259    set_id = edje_edit_image_set_id_get(obj, name);
9260    if (set_id < 0)
9261      return NULL;
9262 
9263    it = eina_hash_iterator_data_new(ed->file->collection);
9264 
9265 #define ITEM_ADD()                                                             \
9266   item = (Edje_Part_Image_Use *)calloc(1, sizeof(Edje_Part_Image_Use));        \
9267   item->group = eina_stringshare_add(pce->entry);                              \
9268   item->part = eina_stringshare_add(part->name);                               \
9269   item->state.name = eina_stringshare_add(part_desc_image->common.state.name); \
9270   item->state.value = part_desc_image->common.state.value;                     \
9271   result = eina_list_append(result, item);
9272 
9273    #define FIND_IN_PART_DESCRIPTION()                        \
9274   if ((part_desc_image->image.id == set_id) &&               \
9275       (part_desc_image->image.set))                          \
9276     {                                                        \
9277        ITEM_ADD();                                           \
9278        if (first_only)                                       \
9279          goto end;                                           \
9280        else                                                  \
9281          continue;                                           \
9282     }                                                        \
9283   for (k = 0; k < part_desc_image->image.tweens_count; k++)  \
9284     {                                                        \
9285        if ((part_desc_image->image.tweens[k]->id == set_id)  \
9286            && (part_desc_image->image.tweens[k]->set))       \
9287          {                                                   \
9288             ITEM_ADD();                                      \
9289             if (first_only)                                  \
9290               goto end;                                      \
9291             else                                             \
9292               continue;                                      \
9293          }                                                   \
9294     }
9295 
9296    EINA_ITERATOR_FOREACH(it, pce)
9297      {
9298         if (!pce->ref) continue;
9299         for (i = 0; i < pce->ref->parts_count; i++)
9300           {
9301              if (!pce->ref->parts) continue;
9302              part = pce->ref->parts[i];
9303              if (part->type == EDJE_PART_TYPE_IMAGE)
9304                {
9305                   part_desc_image = (Edje_Part_Description_Image *)part->default_desc;
9306                   FIND_IN_PART_DESCRIPTION();
9307                   for (j = 0; j < part->other.desc_count; j++)
9308                     {
9309                        part_desc_image = (Edje_Part_Description_Image *)part->other.desc[j];
9310                        FIND_IN_PART_DESCRIPTION();
9311                     }
9312                }
9313           }
9314      }
9315    #undef ITEM_ADD
9316    #undef FIND_IN_PART_DESCRIPTION
9317 end:
9318    eina_iterator_free(it);
9319 
9320    return result;
9321 }
9322 
9323 EAPI Eina_Bool
edje_edit_image_set_del(Evas_Object * obj,const char * name)9324 edje_edit_image_set_del(Evas_Object *obj, const char *name)
9325 {
9326    Edje_Image_Directory_Set *de = NULL, *de_last = NULL;
9327    Edje_Image_Directory_Set_Entry *dim = NULL;
9328    Eet_File *eetf;
9329    unsigned int i, j, k;
9330    Eina_List *used;
9331    Eina_Iterator *it;
9332    Edje_Part_Collection_Directory_Entry *pce;
9333 
9334    GET_ED_OR_RETURN(EINA_FALSE);
9335 
9336    if (!ed->file) return EINA_FALSE;
9337    if (!ed->file->image_dir) return EINA_FALSE;
9338    /* check if used */
9339    used = edje_edit_set_usage_list_get(obj, name, EINA_TRUE);
9340    if (used)
9341      {
9342         edje_edit_image_usage_list_free(used);
9343         WRN("Set \"%s\" is used", name);
9344         return EINA_FALSE;
9345      }
9346    edje_edit_image_usage_list_free(used);
9347 
9348    /* find set */
9349    for (i = 0; i < ed->file->image_dir->sets_count; ++i)
9350      {
9351         de = ed->file->image_dir->sets + i;
9352         if ((de->name) && (!strcmp(name, de->name)))
9353           break;
9354      }
9355    if (i == ed->file->image_dir->sets_count) return EINA_FALSE;
9356    de_last = ed->file->image_dir->sets + ed->file->image_dir->sets_count - 1;
9357 
9358    /* clear all links to images */
9359    EINA_LIST_FREE(de->entries, dim)
9360       free(dim);
9361 
9362    --ed->file->image_dir->sets_count;
9363 
9364    /* open the eet file */
9365    eetf = _edje_edit_eet_open(ed, EET_FILE_MODE_READ_WRITE);
9366    if (!eetf)
9367      return EINA_FALSE;
9368 
9369    if (de_last->id != de->id)
9370      {
9371         Edje_Part *part;
9372         Edje_Part_Description_Image *part_desc_image;
9373 
9374         de->name = de_last->name;
9375         it = eina_hash_iterator_data_new(ed->file->collection);
9376         EINA_ITERATOR_FOREACH(it, pce)
9377           {
9378              if (!pce->ref) continue;
9379              for (i = 0; i < pce->ref->parts_count; i++)
9380                {
9381                   if (!pce->ref->parts) continue;
9382                   part = pce->ref->parts[i];
9383                   if (part->type == EDJE_PART_TYPE_IMAGE)
9384                     {
9385                        part_desc_image = (Edje_Part_Description_Image *)part->default_desc;
9386                        if ((part_desc_image->image.id == de_last->id) && (part_desc_image->image.set))
9387                          part_desc_image->image.id = de->id;
9388                        for (k = 0; k < part_desc_image->image.tweens_count; k++)
9389                          if ((part_desc_image->image.id == de_last->id) && (part_desc_image->image.set))
9390                            part_desc_image->image.id = de->id;
9391 
9392                        for (j = 0; j < part->other.desc_count; j++)
9393                          {
9394                             part_desc_image = (Edje_Part_Description_Image *)part->other.desc[j];
9395                             if ((part_desc_image->image.id == de_last->id) && (part_desc_image->image.set))
9396                               part_desc_image->image.id = de->id;
9397                             for (k = 0; k < part_desc_image->image.tweens_count; k++)
9398                               if ((part_desc_image->image.id == de_last->id) && (part_desc_image->image.set))
9399                                 part_desc_image->image.id = de->id;
9400                          }
9401                     }
9402                }
9403              if (!_edje_edit_collection_save(eetf, pce->ref))
9404                {
9405                   _edje_edit_eet_close(eetf);
9406                   return EINA_FALSE;
9407                }
9408           }
9409         eina_iterator_free(it);
9410      }
9411    ed->file->image_dir->sets = realloc(ed->file->image_dir->sets,
9412                                           sizeof(Edje_Image_Directory_Set_Entry) *
9413                                           ed->file->image_dir->sets_count);
9414 
9415    _edje_edit_eet_close(eetf);
9416 
9417    return EINA_TRUE;
9418 }
9419 
9420 EAPI Eina_List *
edje_edit_image_set_images_list_get(Evas_Object * obj,const char * name)9421 edje_edit_image_set_images_list_get(Evas_Object *obj, const char *name)
9422 {
9423    Eina_List *images = NULL, *l;
9424    Edje_Image_Directory_Set *de = NULL;
9425    Edje_Image_Directory_Set_Entry *dim = NULL;
9426    unsigned int i;
9427 
9428    GET_ED_OR_RETURN(NULL);
9429 
9430    if (!ed->file) return NULL;
9431    if (!ed->file->image_dir) return NULL;
9432    if (!name) return NULL;
9433 
9434    for (i = 0; i < ed->file->image_dir->sets_count; ++i)
9435      {
9436         de = ed->file->image_dir->sets + i;
9437         if ((de->name) && (!strcmp(name, de->name)))
9438           break;
9439      }
9440    if (i == ed->file->image_dir->sets_count) return NULL;
9441 
9442    EINA_LIST_FOREACH(de->entries, l, dim)
9443      {
9444         images = eina_list_append(images, eina_stringshare_add(dim->name));
9445      }
9446 
9447    return images;
9448 }
9449 
9450 EAPI Eina_Bool
edje_edit_image_set_image_add(Evas_Object * obj,const char * set_name,const char * name)9451 edje_edit_image_set_image_add(Evas_Object *obj, const char *set_name, const char *name)
9452 {
9453    Edje_Image_Directory_Set *de = NULL;
9454    Edje_Image_Directory_Set_Entry *dim = NULL;
9455    unsigned int i;
9456    int id;
9457 
9458    GET_ED_OR_RETURN(EINA_FALSE);
9459 
9460    if (!ed->file) return EINA_FALSE;
9461    if (!ed->file->image_dir) return EINA_FALSE;
9462    if (!name) return EINA_FALSE;
9463    id = edje_edit_image_id_get(obj, name);
9464    if (id < 0) return EINA_FALSE;
9465 
9466    for (i = 0; i < ed->file->image_dir->sets_count; ++i)
9467      {
9468         de = ed->file->image_dir->sets + i;
9469         if ((de->name) && (!strcmp(set_name, de->name)))
9470           break;
9471      }
9472    if (i == ed->file->image_dir->sets_count) return EINA_FALSE;
9473 
9474    dim = (Edje_Image_Directory_Set_Entry *)calloc(1, sizeof(Edje_Image_Directory_Set_Entry));
9475    dim->name = name;
9476    dim->id = id;
9477    de->entries = eina_list_append(de->entries, dim);
9478 
9479    return EINA_TRUE;
9480 }
9481 
9482 EAPI Eina_Bool
edje_edit_image_set_image_del(Evas_Object * obj,const char * set_name,unsigned int place)9483 edje_edit_image_set_image_del(Evas_Object *obj, const char *set_name, unsigned int place)
9484 {
9485    Edje_Image_Directory_Set *de = NULL;
9486    Edje_Image_Directory_Set_Entry *dim = NULL;
9487    unsigned int i;
9488 
9489    GET_ED_OR_RETURN(EINA_FALSE);
9490 
9491    if (!ed->file) return EINA_FALSE;
9492    if (!ed->file->image_dir) return EINA_FALSE;
9493 
9494    for (i = 0; i < ed->file->image_dir->sets_count; ++i)
9495      {
9496         de = ed->file->image_dir->sets + i;
9497         if ((de->name) && (!strcmp(set_name, de->name)))
9498           break;
9499      }
9500    if (i == ed->file->image_dir->sets_count) return EINA_FALSE;
9501 
9502    dim = eina_list_nth(de->entries, place);
9503    if (!dim) return EINA_FALSE;
9504 
9505    de->entries = eina_list_remove_list(de->entries, eina_list_nth_list(de->entries, place));
9506    free(dim);
9507 
9508    return EINA_TRUE;
9509 }
9510 
9511 #define FUNC_IMAGE_SET_API_SIZE(Value) \
9512  EAPI Eina_Bool \
9513  edje_edit_image_set_image_##Value##_get(Evas_Object *obj, const char *set_name, unsigned int place, int *w, int *h) \
9514  { \
9515     Edje_Image_Directory_Set *de = NULL; \
9516     Edje_Image_Directory_Set_Entry *dim = NULL; \
9517     unsigned int i; \
9518     GET_ED_OR_RETURN(EINA_FALSE); \
9519     if (!ed->file) return EINA_FALSE; \
9520     if (!ed->file->image_dir) return EINA_FALSE; \
9521     for (i = 0; i < ed->file->image_dir->sets_count; ++i) \
9522       { \
9523          de = ed->file->image_dir->sets + i; \
9524          if ((de->name) && (!strcmp(set_name, de->name))) \
9525            break; \
9526       } \
9527     if (i == ed->file->image_dir->sets_count) return EINA_FALSE; \
9528     dim = eina_list_nth(de->entries, place); \
9529     if (!dim) return EINA_FALSE; \
9530     if (w) *w = dim->size.Value.w; \
9531     if (h) *h = dim->size.Value.h; \
9532     return EINA_TRUE; \
9533  } \
9534  EAPI Eina_Bool \
9535  edje_edit_image_set_image_##Value##_set(Evas_Object *obj, const char *set_name, unsigned int place, int w, int h) \
9536  { \
9537     Edje_Image_Directory_Set *de = NULL; \
9538     Edje_Image_Directory_Set_Entry *dim = NULL; \
9539     unsigned int i; \
9540     GET_ED_OR_RETURN(EINA_FALSE); \
9541     if (!ed->file) return EINA_FALSE; \
9542     if (!ed->file->image_dir) return EINA_FALSE; \
9543     for (i = 0; i < ed->file->image_dir->sets_count; ++i) \
9544       { \
9545          de = ed->file->image_dir->sets + i; \
9546          if ((de->name) && (!strcmp(set_name, de->name))) \
9547            break; \
9548       } \
9549     if (i == ed->file->image_dir->sets_count) return EINA_FALSE; \
9550     dim = eina_list_nth(de->entries, place); \
9551     if (!dim) return EINA_FALSE; \
9552     dim->size.Value.w = w; \
9553     dim->size.Value.h = h; \
9554     return EINA_TRUE; \
9555  }
9556 
9557 FUNC_IMAGE_SET_API_SIZE(min);
9558 FUNC_IMAGE_SET_API_SIZE(max);
9559 
9560 EAPI Eina_Bool
edje_edit_image_set_image_border_get(Evas_Object * obj,const char * set_name,unsigned int place,int * l,int * r,int * t,int * b)9561 edje_edit_image_set_image_border_get(Evas_Object *obj, const char *set_name, unsigned int place, int *l, int *r, int *t, int *b)
9562 {
9563    Edje_Image_Directory_Set *de = NULL;
9564    Edje_Image_Directory_Set_Entry *dim = NULL;
9565    unsigned int i;
9566 
9567    GET_ED_OR_RETURN(EINA_FALSE);
9568 
9569    if (!ed->file) return EINA_FALSE;
9570    if (!ed->file->image_dir) return EINA_FALSE;
9571 
9572    for (i = 0; i < ed->file->image_dir->sets_count; ++i)
9573      {
9574         de = ed->file->image_dir->sets + i;
9575         if ((de->name) && (!strcmp(set_name, de->name)))
9576           break;
9577      }
9578    if (i == ed->file->image_dir->sets_count) return EINA_FALSE;
9579 
9580    dim = eina_list_nth(de->entries, place);
9581    if (!dim) return EINA_FALSE;
9582 
9583    if (l) *l = dim->border.l;
9584    if (r) *r = dim->border.r;
9585    if (t) *t = dim->border.t;
9586    if (b) *b = dim->border.b;
9587 
9588    return EINA_TRUE;
9589 }
9590 
9591 EAPI Eina_Bool
edje_edit_image_set_image_border_set(Evas_Object * obj,const char * set_name,unsigned int place,int l,int r,int t,int b)9592 edje_edit_image_set_image_border_set(Evas_Object *obj, const char *set_name, unsigned int place, int l, int r, int t, int b)
9593 {
9594    Edje_Image_Directory_Set *de = NULL;
9595    Edje_Image_Directory_Set_Entry *dim = NULL;
9596    unsigned int i;
9597 
9598    GET_ED_OR_RETURN(EINA_FALSE);
9599 
9600    if (!ed->file) return EINA_FALSE;
9601    if (!ed->file->image_dir) return EINA_FALSE;
9602 
9603    for (i = 0; i < ed->file->image_dir->sets_count; ++i)
9604      {
9605         de = ed->file->image_dir->sets + i;
9606         if ((de->name) && (!strcmp(set_name, de->name)))
9607           break;
9608      }
9609    if (i == ed->file->image_dir->sets_count) return EINA_FALSE;
9610 
9611    dim = eina_list_nth(de->entries, place);
9612    if (!dim) return EINA_FALSE;
9613 
9614    if (l >= 0) dim->border.l = l;
9615    if (r >= 0) dim->border.r = r;
9616    if (t >= 0) dim->border.t = t;
9617    if (b >= 0) dim->border.b = b;
9618 
9619    return EINA_TRUE;
9620 }
9621 
9622 EAPI double
edje_edit_image_set_image_border_scale_get(Evas_Object * obj,const char * set_name,unsigned int place)9623 edje_edit_image_set_image_border_scale_get(Evas_Object *obj, const char *set_name, unsigned int place)
9624 {
9625    Edje_Image_Directory_Set *de = NULL;
9626    Edje_Image_Directory_Set_Entry *dim = NULL;
9627    unsigned int i;
9628 
9629    GET_ED_OR_RETURN(-1);
9630 
9631    if (!ed->file) return -1;
9632    if (!ed->file->image_dir) return -1;
9633 
9634    for (i = 0; i < ed->file->image_dir->sets_count; ++i)
9635      {
9636         de = ed->file->image_dir->sets + i;
9637         if ((de->name) && (!strcmp(set_name, de->name)))
9638           break;
9639      }
9640    if (i == ed->file->image_dir->sets_count) return -1;
9641 
9642    dim = eina_list_nth(de->entries, place);
9643    if (!dim) return -1;
9644 
9645    return dim->border.scale_by;
9646 }
9647 
9648 EAPI Eina_Bool
edje_edit_image_set_image_border_scale_set(Evas_Object * obj,const char * set_name,unsigned int place,double scale_by)9649 edje_edit_image_set_image_border_scale_set(Evas_Object *obj, const char *set_name, unsigned int place, double scale_by)
9650 {
9651    Edje_Image_Directory_Set *de = NULL;
9652    Edje_Image_Directory_Set_Entry *dim = NULL;
9653    unsigned int i;
9654 
9655    GET_ED_OR_RETURN(EINA_FALSE);
9656 
9657    if (!ed->file) return EINA_FALSE;
9658    if (!ed->file->image_dir) return EINA_FALSE;
9659 
9660    for (i = 0; i < ed->file->image_dir->sets_count; ++i)
9661      {
9662         de = ed->file->image_dir->sets + i;
9663         if ((de->name) && (!strcmp(set_name, de->name)))
9664           break;
9665      }
9666    if (i == ed->file->image_dir->sets_count) return EINA_FALSE;
9667 
9668    dim = eina_list_nth(de->entries, place);
9669    if (!dim) return EINA_FALSE;
9670 
9671    if (scale_by >= 0) dim->border.scale_by = scale_by;
9672 
9673    return EINA_TRUE;
9674 }
9675 
9676 /****************/
9677 /*  VECTOR API  */
9678 /****************/
9679 
9680 EAPI Eina_List *
edje_edit_vectors_list_get(Evas_Object * obj)9681 edje_edit_vectors_list_get(Evas_Object *obj)
9682 {
9683    Eina_List *vectors = NULL;
9684    unsigned int i;
9685 
9686    GET_ED_OR_RETURN(NULL);
9687 
9688    if (!ed->file) return NULL;
9689    if (!ed->file->image_dir) return NULL;
9690 
9691    for (i = 0; i < ed->file->image_dir->vectors_count; ++i)
9692      vectors = eina_list_append(vectors,
9693                                eina_stringshare_add(ed->file->image_dir->vectors[i].entry));
9694 
9695    return vectors;
9696 }
9697 
9698 EAPI int
edje_edit_vector_id_get(Evas_Object * obj,const char * vector_name)9699 edje_edit_vector_id_get(Evas_Object *obj, const char *vector_name)
9700 {
9701    GET_EED_OR_RETURN(-1);
9702 
9703    return _edje_vector_id_find(eed, vector_name);
9704 }
9705 
9706 EAPI Eina_List *
edje_edit_vector_usage_list_get(Evas_Object * obj,const char * name,Eina_Bool first_only)9707 edje_edit_vector_usage_list_get(Evas_Object *obj, const char *name, Eina_Bool first_only)
9708 {
9709    Eina_List *result = NULL;
9710    Eina_Iterator *it;
9711    Edje_Part_Collection_Directory_Entry *pce;
9712    Edje_Part_Image_Use *item;
9713    Edje_Part *part;
9714    Edje_Part_Description_Vector *part_desc_vector;
9715    unsigned int i, j;
9716    int vector_id;
9717 
9718    GET_ED_OR_RETURN(NULL);
9719 
9720    vector_id = edje_edit_vector_id_get(obj, name);
9721    if (vector_id < 0)
9722      return NULL;
9723 
9724    it = eina_hash_iterator_data_new(ed->file->collection);
9725 
9726 #define ITEM_ADD()                                                             \
9727   item = (Edje_Part_Image_Use *)calloc(1, sizeof(Edje_Part_Image_Use));        \
9728   item->group = eina_stringshare_add(pce->entry);                              \
9729   item->part = eina_stringshare_add(part->name);                               \
9730   item->state.name = eina_stringshare_add(part_desc_vector->common.state.name);\
9731   item->state.value = part_desc_vector->common.state.value;                    \
9732   result = eina_list_append(result, item);
9733 
9734 #define FIND_IN_PART_DESCRIPTION()                           \
9735   if (part_desc_vector->vg.id == vector_id)                  \
9736     {                                                        \
9737        ITEM_ADD();                                           \
9738        if (first_only)                                       \
9739          goto end;                                           \
9740        else                                                  \
9741          continue;                                           \
9742     }
9743 
9744    EINA_ITERATOR_FOREACH(it, pce)
9745      {
9746         if (!pce->ref) continue;
9747         for (i = 0; i < pce->ref->parts_count; i++)
9748           {
9749              if (!pce->ref->parts) continue;
9750              part = pce->ref->parts[i];
9751              if (part->type == EDJE_PART_TYPE_VECTOR)
9752                {
9753                   part_desc_vector = (Edje_Part_Description_Vector *)part->default_desc;
9754                   FIND_IN_PART_DESCRIPTION();
9755                   for (j = 0; j < part->other.desc_count; j++)
9756                     {
9757                        part_desc_vector = (Edje_Part_Description_Vector *)part->other.desc[j];
9758                        FIND_IN_PART_DESCRIPTION();
9759                     }
9760                }
9761           }
9762      }
9763 
9764    #undef ITEM_ADD
9765    #undef FIND_IN_PART_DESCRIPTION
9766 end:
9767    eina_iterator_free(it);
9768 
9769    return result;
9770 }
9771 
9772 EAPI Eina_Bool
edje_edit_vector_del(Evas_Object * obj,const char * name)9773 edje_edit_vector_del(Evas_Object *obj, const char *name)
9774 {
9775    Edje_Vector_Directory_Entry *de, *de_last;
9776    unsigned int i, j;
9777    Eina_List *used;
9778    Eina_Iterator *it;
9779    Edje_Part_Collection_Directory_Entry *pce;
9780 
9781    GET_EED_OR_RETURN(EINA_FALSE);
9782    GET_ED_OR_RETURN(EINA_FALSE);
9783 
9784    if (!name) return EINA_FALSE;
9785    if (!ed->file) return EINA_FALSE;
9786    if (!ed->path) return EINA_FALSE;
9787 
9788    used = edje_edit_vector_usage_list_get(obj, name, EINA_TRUE);
9789    if (used)
9790      {
9791         edje_edit_image_usage_list_free(used);
9792         WRN("Vector \"%s\" is used", name);
9793         return EINA_FALSE;
9794      }
9795    edje_edit_image_usage_list_free(used);
9796 
9797    /* Create Image_Directory if not exist */
9798    if (!ed->file->image_dir)
9799      goto invalid_image;
9800 
9801    for (i = 0; i < ed->file->image_dir->vectors_count; ++i)
9802      {
9803         de = ed->file->image_dir->vectors + i;
9804 
9805         if ((de->entry) && (!strcmp(name, de->entry)))
9806           break;
9807      }
9808    if (i == ed->file->image_dir->vectors_count)
9809      goto invalid_image;
9810 
9811    de_last = ed->file->image_dir->vectors + ed->file->image_dir->vectors_count - 1;
9812 
9813    {
9814       char entry[PATH_MAX];
9815       char last_entry[PATH_MAX];
9816       Eet_File *eetf;
9817       void *data;
9818       int size = 0;
9819 
9820       /* open the eet file */
9821       eetf = _edje_edit_eet_open(ed, EET_FILE_MODE_READ_WRITE);
9822       if (!eetf)
9823         return EINA_FALSE;
9824 
9825       snprintf(entry, sizeof(entry), "edje/vectors/%i", de->id);
9826 
9827       if (eet_delete(eetf, entry) <= 0)
9828         {
9829            ERR("Unable to delete \"%s\" vector entry", entry);
9830            _edje_edit_eet_close(eetf);
9831            return EINA_FALSE;
9832         }
9833       if (de_last->id != de->id)
9834         {
9835            snprintf(last_entry, sizeof(last_entry), "edje/vectors/%i", de_last->id);
9836            data = eet_read(eetf, last_entry, &size);
9837            eet_delete(eetf, last_entry);
9838            eet_write(eetf, entry, data, size, 0);
9839         }
9840 
9841       _edje_if_string_free(ed, &de->entry);
9842       --ed->file->image_dir->vectors_count;
9843 
9844       if (de_last->id != de->id)
9845         {
9846            Edje_Part *part;
9847            Edje_Part_Description_Vector *part_desc_vector;
9848 
9849            de->entry = de_last->entry;
9850            it = eina_hash_iterator_data_new(ed->file->collection);
9851            EINA_ITERATOR_FOREACH(it, pce)
9852              {
9853                 if (!pce->ref) continue;
9854                 for (i = 0; i < pce->ref->parts_count; i++)
9855                   {
9856                      if (!pce->ref->parts) continue;
9857                      part = pce->ref->parts[i];
9858                      if (part->type == EDJE_PART_TYPE_VECTOR)
9859                        {
9860                           part_desc_vector = (Edje_Part_Description_Vector *)part->default_desc;
9861                           if (part_desc_vector->vg.id == de_last->id)
9862                             part_desc_vector->vg.id = de->id;
9863 
9864                           for (j = 0; j < part->other.desc_count; j++)
9865                             {
9866                                part_desc_vector = (Edje_Part_Description_Vector *)part->other.desc[j];
9867                                if (part_desc_vector->vg.id == de_last->id)
9868                                  part_desc_vector->vg.id = de->id;
9869                             }
9870                        }
9871                   }
9872                 if (!_edje_edit_collection_save(eetf, pce->ref))
9873                   {
9874                      _edje_edit_eet_close(eetf);
9875                      return EINA_FALSE;
9876                   }
9877              }
9878            eina_iterator_free(it);
9879         }
9880       ed->file->image_dir->vectors = realloc(ed->file->image_dir->vectors,
9881                                              sizeof(Edje_Vector_Directory_Entry) *
9882                                              ed->file->image_dir->vectors_count);
9883       /* write the edje_file */
9884       if (!_edje_edit_edje_file_save(eetf, ed->file))
9885         {
9886            _edje_edit_eet_close(eetf);
9887            return EINA_FALSE;
9888         }
9889 
9890       _edje_edit_eet_close(eetf);
9891    }
9892    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
9893 
9894    return EINA_TRUE;
9895 
9896 invalid_image:
9897    WRN("Unable to find vector entry part \"%s\"", name);
9898    return EINA_FALSE;
9899 }
9900 
9901 /****************/
9902 /*  IMAGES API  */
9903 /****************/
9904 
9905 EAPI Eina_List *
edje_edit_images_list_get(Evas_Object * obj)9906 edje_edit_images_list_get(Evas_Object *obj)
9907 {
9908    Eina_List *images = NULL;
9909    unsigned int i;
9910 
9911    GET_ED_OR_RETURN(NULL);
9912 
9913    if (!ed->file) return NULL;
9914    if (!ed->file->image_dir) return NULL;
9915 
9916    //printf("GET IMAGES LIST for %s\n", ed->file->path);
9917    for (i = 0; i < ed->file->image_dir->entries_count; ++i)
9918      images = eina_list_append(images,
9919                                eina_stringshare_add(ed->file->image_dir->entries[i].entry));
9920 
9921    return images;
9922 }
9923 
9924 EAPI Eina_Bool
edje_edit_image_add(Evas_Object * obj,const char * path)9925 edje_edit_image_add(Evas_Object *obj, const char *path)
9926 {
9927    Edje_Image_Directory_Entry *de;
9928    unsigned int i;
9929    int free_id = -1;
9930    const char *name;
9931 
9932    GET_ED_OR_RETURN(EINA_FALSE);
9933 
9934    if (!path) return EINA_FALSE;
9935    if (!ed->file) return EINA_FALSE;
9936    if (!ed->path) return EINA_FALSE;
9937 
9938    /* Create Image_Directory if not exist */
9939    if (!ed->file->image_dir)
9940      {
9941         ed->file->image_dir = _alloc(sizeof(Edje_Image_Directory));
9942         if (!ed->file->image_dir) return EINA_FALSE;
9943      }
9944 
9945    /* Image name */
9946    name = ecore_file_file_get(path);
9947 
9948    /* Loop trough image directory to find if image exist */
9949    for (i = 0; i < ed->file->image_dir->entries_count; ++i)
9950      {
9951         de = ed->file->image_dir->entries + i;
9952 
9953         if (!de->entry)
9954           free_id = i;
9955         else if (!strcmp(name, de->entry))
9956           return EINA_FALSE;
9957      }
9958 
9959    if (free_id == -1)
9960      {
9961         Edje_Image_Directory_Entry *tmp;
9962         unsigned int count;
9963 
9964         count = ed->file->image_dir->entries_count + 1;
9965 
9966         tmp = realloc(ed->file->image_dir->entries,
9967                       sizeof (Edje_Image_Directory_Entry) * count);
9968         if (!tmp) return EINA_FALSE;
9969 
9970         ed->file->image_dir->entries = tmp;
9971         free_id = ed->file->image_dir->entries_count;
9972         ed->file->image_dir->entries_count = count;
9973      }
9974 
9975    /* Set Image Entry */
9976    de = ed->file->image_dir->entries + free_id;
9977    de->entry = eina_stringshare_add(name);
9978    de->id = free_id;
9979    de->source_type = 1;
9980    de->source_param = 1;
9981 
9982    /* Import image */
9983    if (!_edje_import_image_file(ed, path, free_id))
9984      {
9985         eina_stringshare_del(de->entry);
9986         de->entry = NULL;
9987         return EINA_FALSE;
9988      }
9989 
9990    return EINA_TRUE;
9991 }
9992 
9993 EAPI Eina_Bool
edje_edit_image_replace(Evas_Object * obj,const char * name,const char * new_name)9994 edje_edit_image_replace(Evas_Object *obj, const char *name, const char *new_name)
9995 {
9996    Eina_Iterator *it;
9997    Edje_Part_Collection_Directory_Entry *pce;
9998    Edje_Part *part;
9999    Eet_File *eetf;
10000    Edje_Part_Description_Image *part_desc_image;
10001    unsigned int i, j, k;
10002    int image_id, new_image_id;
10003 
10004    GET_ED_OR_RETURN(EINA_FALSE);
10005 
10006    image_id = edje_edit_image_id_get(obj, name);
10007    new_image_id = edje_edit_image_id_get(obj, new_name);
10008    if ((image_id < 0) || (new_image_id < 0))
10009      return EINA_FALSE;
10010 
10011    it = eina_hash_iterator_data_new(ed->file->collection);
10012 
10013    /* open the eet file */
10014    eetf = _edje_edit_eet_open(ed, EET_FILE_MODE_READ_WRITE);
10015    if (!eetf)
10016      {
10017         eina_iterator_free(it);
10018         return EINA_FALSE;
10019      }
10020 
10021    EINA_ITERATOR_FOREACH(it, pce)
10022      {
10023         for (i = 0; i < pce->ref->parts_count; i++)
10024           {
10025              part = pce->ref->parts[i];
10026              if (part->type == EDJE_PART_TYPE_IMAGE)
10027                {
10028                   part_desc_image = (Edje_Part_Description_Image *)part->default_desc;
10029                   if (part_desc_image->image.id == image_id)
10030                     part_desc_image->image.id = new_image_id;
10031                   for (k = 0; k < part_desc_image->image.tweens_count; k++)
10032                     if (part_desc_image->image.tweens[k]->id == image_id)
10033                       part_desc_image->image.id = new_image_id;
10034                   for (j = 0; j < part->other.desc_count; j++)
10035                     {
10036                        part_desc_image = (Edje_Part_Description_Image *)part->other.desc[j];
10037                        if (part_desc_image->image.id == image_id)
10038                          part_desc_image->image.id = new_image_id;
10039                        for (k = 0; k < part_desc_image->image.tweens_count; k++)
10040                          if (part_desc_image->image.tweens[k]->id == image_id)
10041                            part_desc_image->image.id = new_image_id;
10042                     }
10043                }
10044              if (!_edje_edit_collection_save(eetf, pce->ref))
10045                {
10046                   _edje_edit_eet_close(eetf);
10047                   eina_iterator_free(it);
10048                   return EINA_FALSE;
10049                }
10050           }
10051      }
10052    eina_iterator_free(it);
10053 
10054    _edje_edit_eet_close(eetf);
10055 
10056    return EINA_TRUE;
10057 }
10058 
10059 EAPI Eina_Bool
edje_edit_image_rename(Evas_Object * obj,const char * name,const char * new_name)10060 edje_edit_image_rename(Evas_Object *obj, const char *name, const char *new_name)
10061 {
10062    Edje_Image_Directory_Entry *de = NULL;
10063    unsigned int i;
10064    GET_ED_OR_RETURN(EINA_FALSE);
10065 
10066    // Check if image with 'new_name' already exists
10067    if (edje_edit_image_id_get(obj, new_name) >= 0)
10068      return EINA_FALSE;
10069 
10070    for (i = 0; i < ed->file->image_dir->entries_count; ++i)
10071      {
10072         de = ed->file->image_dir->entries + i;
10073         if ((de->entry) && (!strcmp(name, de->entry)))
10074           break;
10075      }
10076    if (i == ed->file->image_dir->entries_count) return EINA_FALSE;
10077 
10078    _edje_if_string_replace(ed, &de->entry, new_name);
10079 
10080    return EINA_TRUE;
10081 }
10082 
10083 EAPI Eina_List *
edje_edit_image_usage_list_get(Evas_Object * obj,const char * name,Eina_Bool first_only)10084 edje_edit_image_usage_list_get(Evas_Object *obj, const char *name, Eina_Bool first_only)
10085 {
10086    Eina_List *result = NULL, *l;
10087    Eina_Iterator *it;
10088    Edje_Part_Collection_Directory_Entry *pce;
10089    Edje_Part_Image_Use *item;
10090    Edje_Part *part;
10091    Edje_Part_Description_Image *part_desc_image;
10092    Edje_Image_Directory_Set *de = NULL;
10093    Edje_Image_Directory_Set_Entry *dim = NULL;
10094    unsigned int i, j, k;
10095    int image_id;
10096 
10097    GET_ED_OR_RETURN(NULL);
10098 
10099    image_id = edje_edit_image_id_get(obj, name);
10100    if (image_id < 0)
10101      return NULL;
10102 
10103    if (edje_edit_image_compression_type_get(obj, name) ==
10104        EDJE_EDIT_IMAGE_COMP_USER)
10105      image_id = -1 - image_id;
10106 
10107    it = eina_hash_iterator_data_new(ed->file->collection);
10108 
10109 #define ITEM_ADD()                                                             \
10110   item = (Edje_Part_Image_Use *)calloc(1, sizeof(Edje_Part_Image_Use));        \
10111   item->group = eina_stringshare_add(pce->entry);                              \
10112   item->part = eina_stringshare_add(part->name);                               \
10113   item->state.name = eina_stringshare_add(part_desc_image->common.state.name); \
10114   item->state.value = part_desc_image->common.state.value;                     \
10115   result = eina_list_append(result, item);
10116 
10117 #define ITEM_SET_ADD()                                                  \
10118   item = (Edje_Part_Image_Use *)calloc(1, sizeof(Edje_Part_Image_Use)); \
10119   item->group = eina_stringshare_add(de->name);                         \
10120   item->part = NULL;                                                    \
10121   item->state.name = NULL;                                              \
10122   item->state.value = -1;                                               \
10123   result = eina_list_append(result, item);
10124 
10125 #define FIND_IN_PART_DESCRIPTION()                           \
10126   if ((part_desc_image->image.id == image_id) &&             \
10127       (!part_desc_image->image.set))                         \
10128     {                                                        \
10129        ITEM_ADD();                                           \
10130        if (first_only)                                       \
10131          goto end;                                           \
10132        else                                                  \
10133          continue;                                           \
10134     }                                                        \
10135   for (k = 0; k < part_desc_image->image.tweens_count; k++)  \
10136     {                                                        \
10137        if ((part_desc_image->image.tweens[k]->id == image_id)\
10138            && (!part_desc_image->image.tweens[k]->set))      \
10139          {                                                   \
10140             ITEM_ADD();                                      \
10141             if (first_only)                                  \
10142               goto end;                                      \
10143             else                                             \
10144               continue;                                      \
10145          }                                                   \
10146     }
10147 
10148    EINA_ITERATOR_FOREACH(it, pce)
10149      {
10150         if (!pce->ref) continue;
10151         for (i = 0; i < pce->ref->parts_count; i++)
10152           {
10153              if (!pce->ref->parts) continue;
10154              part = pce->ref->parts[i];
10155              if (part->type == EDJE_PART_TYPE_IMAGE)
10156                {
10157                   part_desc_image = (Edje_Part_Description_Image *)part->default_desc;
10158                   FIND_IN_PART_DESCRIPTION();
10159                   for (j = 0; j < part->other.desc_count; j++)
10160                     {
10161                        part_desc_image = (Edje_Part_Description_Image *)part->other.desc[j];
10162                        FIND_IN_PART_DESCRIPTION();
10163                     }
10164                }
10165           }
10166      }
10167 
10168    /* NOW CHECKING IF IMAGE IS USED INSIDE OF SET */
10169    for (i = 0; i < ed->file->image_dir->sets_count; ++i)
10170      {
10171         de = ed->file->image_dir->sets + i;
10172         EINA_LIST_FOREACH(de->entries, l, dim)
10173           {
10174              if (dim->id == image_id)
10175                {
10176                   ITEM_SET_ADD()
10177                }
10178           }
10179      }
10180 
10181    #undef ITEM_ADD
10182    #undef FIND_IN_PART_DESCRIPTION
10183 end:
10184    eina_iterator_free(it);
10185 
10186    return result;
10187 }
10188 
10189 EAPI void
edje_edit_image_usage_list_free(Eina_List * list)10190 edje_edit_image_usage_list_free(Eina_List *list)
10191 {
10192    Edje_Part_Image_Use *item;
10193    EINA_LIST_FREE(list, item)
10194      {
10195         eina_stringshare_del(item->group);
10196         eina_stringshare_del(item->part);
10197         eina_stringshare_del(item->state.name);
10198         free(item);
10199      }
10200 }
10201 
10202 EAPI Eina_Bool
edje_edit_image_del(Evas_Object * obj,const char * name)10203 edje_edit_image_del(Evas_Object *obj, const char *name)
10204 {
10205    Edje_Image_Directory_Entry *de, *de_last;
10206    unsigned int i, j, k;
10207    Eina_List *used;
10208    Eina_Iterator *it;
10209    Edje_Part_Collection_Directory_Entry *pce;
10210 
10211    GET_EED_OR_RETURN(EINA_FALSE);
10212    GET_ED_OR_RETURN(EINA_FALSE);
10213 
10214    if (!name) return EINA_FALSE;
10215    if (!ed->file) return EINA_FALSE;
10216    if (!ed->path) return EINA_FALSE;
10217 
10218    used = edje_edit_image_usage_list_get(obj, name, EINA_TRUE);
10219    if (used)
10220      {
10221         edje_edit_image_usage_list_free(used);
10222         WRN("Image \"%s\" is used", name);
10223         return EINA_FALSE;
10224      }
10225    edje_edit_image_usage_list_free(used);
10226 
10227    /* Create Image_Directory if not exist */
10228    if (!ed->file->image_dir)
10229      goto invalid_image;
10230 
10231    for (i = 0; i < ed->file->image_dir->entries_count; ++i)
10232      {
10233         de = ed->file->image_dir->entries + i;
10234 
10235         if ((de->entry) && (!strcmp(name, de->entry)))
10236           break;
10237      }
10238    if (i == ed->file->image_dir->entries_count)
10239      goto invalid_image;
10240 
10241    de_last = ed->file->image_dir->entries + ed->file->image_dir->entries_count - 1;
10242 
10243    {
10244       char entry[PATH_MAX];
10245       char last_entry[PATH_MAX];
10246       Eet_File *eetf;
10247       void *data;
10248       int size = 0;
10249 
10250       /* open the eet file */
10251       eetf = _edje_edit_eet_open(ed, EET_FILE_MODE_READ_WRITE);
10252       if (!eetf)
10253         return EINA_FALSE;
10254 
10255       snprintf(entry, sizeof(entry), "edje/images/%i", de->id);
10256 
10257       if (eet_delete(eetf, entry) <= 0)
10258         {
10259            ERR("Unable to delete \"%s\" font entry", entry);
10260            _edje_edit_eet_close(eetf);
10261            return EINA_FALSE;
10262         }
10263       if (de_last->id != de->id)
10264         {
10265            snprintf(last_entry, sizeof(last_entry), "edje/images/%i", de_last->id);
10266            data = eet_read(eetf, last_entry, &size);
10267            eet_delete(eetf, last_entry);
10268            eet_write(eetf, entry, data, size, 0);
10269         }
10270 
10271       _edje_if_string_free(ed, &de->entry);
10272       --ed->file->image_dir->entries_count;
10273 
10274       if (de_last->id != de->id)
10275         {
10276            Edje_Part *part;
10277            Edje_Part_Description_Image *part_desc_image;
10278 
10279            de->entry = de_last->entry;
10280            it = eina_hash_iterator_data_new(ed->file->collection);
10281            EINA_ITERATOR_FOREACH(it, pce)
10282              {
10283                 if (!pce->ref) continue;
10284                 for (i = 0; i < pce->ref->parts_count; i++)
10285                   {
10286                      if (!pce->ref->parts) continue;
10287                      part = pce->ref->parts[i];
10288                      if (part->type == EDJE_PART_TYPE_IMAGE)
10289                        {
10290                           part_desc_image = (Edje_Part_Description_Image *)part->default_desc;
10291                           if (part_desc_image->image.id == de_last->id)
10292                             part_desc_image->image.id = de->id;
10293                           for (k = 0; k < part_desc_image->image.tweens_count; k++)
10294                             if (part_desc_image->image.id == de_last->id)
10295                               part_desc_image->image.id = de->id;
10296 
10297                           for (j = 0; j < part->other.desc_count; j++)
10298                             {
10299                                part_desc_image = (Edje_Part_Description_Image *)part->other.desc[j];
10300                                if (part_desc_image->image.id == de_last->id)
10301                                  part_desc_image->image.id = de->id;
10302                                for (k = 0; k < part_desc_image->image.tweens_count; k++)
10303                                  if (part_desc_image->image.id == de_last->id)
10304                                    part_desc_image->image.id = de->id;
10305                             }
10306                        }
10307                   }
10308                 if (!_edje_edit_collection_save(eetf, pce->ref))
10309                   {
10310                      _edje_edit_eet_close(eetf);
10311                      return EINA_FALSE;
10312                   }
10313              }
10314            eina_iterator_free(it);
10315         }
10316       ed->file->image_dir->entries = realloc(ed->file->image_dir->entries,
10317                                              sizeof(Edje_Image_Directory_Entry) *
10318                                              ed->file->image_dir->entries_count);
10319       /* write the edje_file */
10320       if (!_edje_edit_edje_file_save(eetf, ed->file))
10321         {
10322            _edje_edit_eet_close(eetf);
10323            return EINA_FALSE;
10324         }
10325 
10326       _edje_edit_eet_close(eetf);
10327    }
10328    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
10329 
10330    return EINA_TRUE;
10331 
10332 invalid_image:
10333    WRN("Unable to find image entry part \"%s\"", name);
10334    return EINA_FALSE;
10335 }
10336 
10337 EAPI Eina_Bool
edje_edit_image_data_add(Evas_Object * obj,const char * name,int id)10338 edje_edit_image_data_add(Evas_Object *obj, const char *name, int id)
10339 {
10340    Edje_Image_Directory_Entry *de;
10341 
10342    GET_ED_OR_RETURN(EINA_FALSE);
10343 
10344    if (!name) return EINA_FALSE;
10345    if (!ed->file) return EINA_FALSE;
10346    if (!ed->path) return EINA_FALSE;
10347 
10348    /* Create Image_Directory if not exist */
10349    if (!ed->file->image_dir)
10350      {
10351         ed->file->image_dir = _alloc(sizeof(Edje_Image_Directory));
10352         if (!ed->file->image_dir) return EINA_FALSE;
10353      }
10354 
10355    /* Loop trough image directory to find if image exist */
10356    if (id < 0) id = -id - 1;
10357    if ((unsigned int)id >= ed->file->image_dir->entries_count) return EINA_FALSE;
10358 
10359    de = ed->file->image_dir->entries + id;
10360    _edje_if_string_replace(ed, &de->entry, name);
10361    de->source_type = 1;
10362    de->source_param = 1;
10363 
10364    return EINA_TRUE;
10365 }
10366 
10367 EAPI int
edje_edit_image_id_get(Evas_Object * obj,const char * image_name)10368 edje_edit_image_id_get(Evas_Object *obj, const char *image_name)
10369 {
10370    GET_EED_OR_RETURN(-1);
10371 
10372    return _edje_image_id_find(eed, image_name);
10373 }
10374 
10375 EAPI Edje_Edit_Image_Comp
edje_edit_image_compression_type_get(Evas_Object * obj,const char * image)10376 edje_edit_image_compression_type_get(Evas_Object *obj, const char *image)
10377 {
10378    Edje_Image_Directory_Entry *de = NULL;
10379    unsigned int i;
10380 
10381    GET_ED_OR_RETURN(-1);
10382 
10383    if (!ed->file) return -1;
10384    if (!ed->file->image_dir) return -1;
10385 
10386    for (i = 0; i < ed->file->image_dir->entries_count; ++i)
10387      {
10388         de = ed->file->image_dir->entries + i;
10389 
10390         if (de->entry
10391             && !strcmp(image, de->entry))
10392           break;
10393      }
10394 
10395    if (i == ed->file->image_dir->entries_count) return -1;
10396 
10397    switch (de->source_type)
10398      {
10399       case EDJE_IMAGE_SOURCE_TYPE_INLINE_PERFECT:
10400         if (de->source_param == 0) // RAW
10401           return EDJE_EDIT_IMAGE_COMP_RAW;
10402         else // COMP
10403           return EDJE_EDIT_IMAGE_COMP_COMP;
10404 
10405       case EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY: // LOSSY
10406         return EDJE_EDIT_IMAGE_COMP_LOSSY;
10407 
10408       case EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC1: // LOSSY_ETC1
10409         return EDJE_EDIT_IMAGE_COMP_LOSSY_ETC1;
10410 
10411       case EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC2: // LOSSY_ETC2
10412         return EDJE_EDIT_IMAGE_COMP_LOSSY_ETC2;
10413 
10414       case EDJE_IMAGE_SOURCE_TYPE_USER: // USER
10415         return EDJE_EDIT_IMAGE_COMP_USER;
10416      }
10417 
10418    return -1;
10419 }
10420 
10421 EAPI Eina_Bool
edje_edit_image_compression_type_set(Evas_Object * obj,const char * image,Edje_Edit_Image_Comp ic)10422 edje_edit_image_compression_type_set(Evas_Object *obj, const char *image, Edje_Edit_Image_Comp ic)
10423 {
10424    Edje_Image_Directory_Entry *de = NULL;
10425    unsigned int i;
10426 
10427    GET_ED_OR_RETURN(EINA_FALSE);
10428 
10429    if (!ed->file) return EINA_FALSE;
10430    if (!ed->file->image_dir) return EINA_FALSE;
10431 
10432    for (i = 0; i < ed->file->image_dir->entries_count; ++i)
10433      {
10434         de = ed->file->image_dir->entries + i;
10435         if ((de->entry) && (!strcmp(image, de->entry)))
10436           break;
10437      }
10438 
10439    if (i == ed->file->image_dir->entries_count) return EINA_FALSE;
10440 
10441    switch (ic)
10442      {
10443       case EDJE_EDIT_IMAGE_COMP_RAW: // RAW
10444         if (de->source_param == 0)
10445           {
10446              de->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_PERFECT;
10447              return EINA_TRUE;
10448           }
10449         else
10450           return EINA_FALSE;
10451 
10452       case EDJE_EDIT_IMAGE_COMP_COMP: // COMP
10453         if (de->source_param == 1)
10454           {
10455              de->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_PERFECT;
10456              return EINA_TRUE;
10457           }
10458         else
10459           return EINA_FALSE;
10460 
10461       case EDJE_EDIT_IMAGE_COMP_LOSSY: // LOSSY
10462       {
10463          de->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY;
10464          return EINA_TRUE;
10465       }
10466 
10467       case EDJE_EDIT_IMAGE_COMP_LOSSY_ETC1: // LOSSY_ETC1
10468       {
10469          de->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC1;
10470          return EINA_TRUE;
10471       }
10472 
10473       case EDJE_EDIT_IMAGE_COMP_LOSSY_ETC2: // LOSSY_ETC2
10474       {
10475          de->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC2;
10476          return EINA_TRUE;
10477       }
10478 
10479       case EDJE_EDIT_IMAGE_COMP_USER: // USER
10480       {
10481          de->source_type = EDJE_IMAGE_SOURCE_TYPE_USER;
10482          return EINA_TRUE;
10483       }
10484      }
10485    return EINA_FALSE;
10486 }
10487 
10488 EAPI int
edje_edit_image_compression_rate_get(Evas_Object * obj,const char * image)10489 edje_edit_image_compression_rate_get(Evas_Object *obj, const char *image)
10490 {
10491    Edje_Image_Directory_Entry *de;
10492    unsigned int i;
10493 
10494    GET_ED_OR_RETURN(-1);
10495 
10496    // Gets the Image Entry
10497    for (i = 0; i < ed->file->image_dir->entries_count; ++i)
10498      {
10499         de = ed->file->image_dir->entries + i;
10500         if (de->entry
10501             && !strcmp(de->entry, image))
10502           break;
10503      }
10504 
10505    if (i == ed->file->image_dir->entries_count) return -1;
10506    if ((de->source_type != EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY)
10507        && (de->source_type != EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC1)
10508        && (de->source_type != EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC2))
10509      return -2;
10510 
10511    return de->source_param;
10512 }
10513 
10514 EAPI const char *
edje_edit_state_image_get(Evas_Object * obj,const char * part,const char * state,double value)10515 edje_edit_state_image_get(Evas_Object *obj, const char *part, const char *state, double value)
10516 {
10517    Edje_Part_Description_Image *img;
10518    const char *image;
10519 
10520    GET_PD_OR_RETURN(NULL);
10521 
10522    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10523      return NULL;
10524 
10525    img = (Edje_Part_Description_Image *)pd;
10526 
10527    if (!img->image.set)
10528      image = _edje_image_name_find(eed, img->image.id);
10529    else
10530      image = _edje_set_name_find(eed, img->image.id);
10531    if (!image) return NULL;
10532 
10533    //printf("GET IMAGE for %s [%s]\n", state, image);
10534    return eina_stringshare_add(image);
10535 }
10536 
10537 EAPI Eina_Bool
edje_edit_state_image_set(Evas_Object * obj,const char * part,const char * state,double value,const char * image)10538 edje_edit_state_image_set(Evas_Object *obj, const char *part, const char *state, double value, const char *image)
10539 {
10540    Edje_Part_Description_Image *img;
10541    int id;
10542    Eina_Bool image_set = EINA_FALSE;
10543 
10544    if ((!obj) || (!part) || (!state) || (!image))
10545      return EINA_FALSE;
10546 
10547    eina_error_set(0);
10548    GET_PD_OR_RETURN(EINA_FALSE);
10549 
10550    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10551      return EINA_FALSE;
10552 
10553 
10554    img = (Edje_Part_Description_Image *)pd;
10555 
10556    id = _edje_image_id_find(eed, image);
10557    if (id <= -1)
10558      {
10559         id = _edje_set_id_find(eed, image);
10560         image_set = EINA_TRUE;
10561      }
10562 
10563    if (id > -1) img->image.id = id;
10564    else return EINA_FALSE;
10565    img->image.set = image_set;
10566 
10567    edje_object_calc_force(obj);
10568    return EINA_TRUE;
10569 }
10570 
10571 EAPI const char *
edje_edit_state_vector_get(Evas_Object * obj,const char * part,const char * state,double value)10572 edje_edit_state_vector_get(Evas_Object *obj, const char *part, const char *state, double value)
10573 {
10574    Edje_Part_Description_Vector *vec;
10575    const char *vector;
10576 
10577    GET_PD_OR_RETURN(NULL);
10578 
10579    if (rp->part->type != EDJE_PART_TYPE_VECTOR)
10580      return NULL;
10581 
10582    vec = (Edje_Part_Description_Vector *)pd;
10583 
10584    vector = _edje_vector_name_find(eed, vec->vg.id);
10585    if (!vector) return NULL;
10586 
10587    //printf("GET IMAGE for %s [%s]\n", state, image);
10588    return eina_stringshare_add(vector);
10589 }
10590 
10591 EAPI Eina_Bool
edje_edit_state_vector_set(Evas_Object * obj,const char * part,const char * state,double value,const char * vector)10592 edje_edit_state_vector_set(Evas_Object *obj, const char *part, const char *state, double value, const char *vector)
10593 {
10594    Edje_Part_Description_Vector *vec;
10595    int id;
10596 
10597    if ((!obj) || (!part) || (!state) || (!vector))
10598      return EINA_FALSE;
10599 
10600    eina_error_set(0);
10601    GET_PD_OR_RETURN(EINA_FALSE);
10602 
10603    if (rp->part->type != EDJE_PART_TYPE_VECTOR)
10604      return EINA_FALSE;
10605 
10606    vec = (Edje_Part_Description_Vector *)pd;
10607 
10608    id = _edje_vector_id_find(eed, vector);
10609 
10610    if (id > -1) vec->vg.id = id;
10611    else return EINA_FALSE;
10612 
10613    edje_object_calc_force(obj);
10614    return EINA_TRUE;
10615 }
10616 
10617 EAPI Eina_List *
edje_edit_state_tweens_list_get(Evas_Object * obj,const char * part,const char * state,double value)10618 edje_edit_state_tweens_list_get(Evas_Object *obj, const char *part, const char *state, double value)
10619 {
10620    Edje_Part_Description_Image *img;
10621    Eina_List *tweens = NULL;
10622    const char *name;
10623    unsigned int i;
10624 
10625    GET_PD_OR_RETURN(NULL);
10626 
10627    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10628      return NULL;
10629 
10630    img = (Edje_Part_Description_Image *)pd;
10631 
10632    for (i = 0; i < img->image.tweens_count; ++i)
10633      {
10634         if (!img->image.tweens[i]->set)
10635           name = _edje_image_name_find(eed, img->image.tweens[i]->id);
10636         else
10637           name = _edje_set_name_find(eed, img->image.tweens[i]->id);
10638         //printf("   t: %s\n", name);
10639         tweens = eina_list_append(tweens, eina_stringshare_add(name));
10640      }
10641 
10642    return tweens;
10643 }
10644 
10645 EAPI Eina_Bool
edje_edit_state_tween_add(Evas_Object * obj,const char * part,const char * state,double value,const char * tween)10646 edje_edit_state_tween_add(Evas_Object *obj, const char *part, const char *state, double value, const char *tween)
10647 {
10648    Edje_Part_Description_Image *img;
10649    Edje_Part_Image_Id **tmp;
10650    Edje_Part_Image_Id *i;
10651    int id;
10652    Eina_Bool set = EINA_FALSE;
10653 
10654    GET_PD_OR_RETURN(EINA_FALSE);
10655 
10656    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10657      return EINA_FALSE;
10658 
10659    id = _edje_image_id_find(eed, tween);
10660    if (id < EINA_FALSE)
10661      {
10662         set = EINA_TRUE;
10663         id = _edje_set_id_find(eed, tween);
10664      }
10665 
10666    if (id < EINA_FALSE) return 0;
10667 
10668    /* alloc Edje_Part_Image_Id */
10669    i = _alloc(sizeof(Edje_Part_Image_Id));
10670    if (!i) return EINA_FALSE;
10671    i->id = id;
10672    i->set = set;
10673 
10674    img = (Edje_Part_Description_Image *)pd;
10675 
10676    /* add to tween list */
10677    tmp = realloc(img->image.tweens,
10678                  sizeof(Edje_Part_Image_Id *) * (img->image.tweens_count + 1));
10679    if (!tmp)
10680      {
10681         free(i);
10682         return EINA_FALSE;
10683      }
10684 
10685    tmp[img->image.tweens_count++] = i;
10686    img->image.tweens = tmp;
10687 
10688    return EINA_TRUE;
10689 }
10690 
10691 EAPI Eina_Bool
edje_edit_state_tween_insert_at(Evas_Object * obj,const char * part,const char * state,double value,const char * tween,int place)10692 edje_edit_state_tween_insert_at(Evas_Object *obj, const char *part, const char *state, double value, const char *tween, int place)
10693 {
10694    Edje_Part_Description_Image *img;
10695    Edje_Part_Image_Id **tmp;
10696    Edje_Part_Image_Id *i;
10697    int id;
10698    unsigned int j;
10699 
10700    if (place < 0)
10701      return EINA_FALSE;
10702 
10703    GET_PD_OR_RETURN(EINA_FALSE);
10704 
10705    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10706      return EINA_FALSE;
10707 
10708    id = _edje_image_id_find(eed, tween);
10709    if (id < EINA_FALSE) return 0;
10710 
10711    /* alloc Edje_Part_Image_Id */
10712    i = _alloc(sizeof(Edje_Part_Image_Id));
10713    if (!i) return EINA_FALSE;
10714    i->id = id;
10715 
10716    img = (Edje_Part_Description_Image *)pd;
10717 
10718    if ((unsigned)place > img->image.tweens_count)
10719      {
10720         free(i);
10721         return EINA_FALSE;
10722      }
10723 
10724    /* add to tween list */
10725    tmp = realloc(img->image.tweens,
10726                  sizeof(Edje_Part_Image_Id *) * (img->image.tweens_count + 1));
10727    if (!tmp)
10728      {
10729         free(i);
10730         return EINA_FALSE;
10731      }
10732 
10733    img->image.tweens_count++;
10734    for (j = img->image.tweens_count - 1; j > (unsigned)place; j--)
10735      tmp[j] = tmp[j - 1];
10736    tmp[place] = i;
10737    img->image.tweens = tmp;
10738 
10739    return EINA_TRUE;
10740 }
10741 
10742 EAPI Eina_Bool
edje_edit_state_tween_del(Evas_Object * obj,const char * part,const char * state,double value,const char * tween)10743 edje_edit_state_tween_del(Evas_Object *obj, const char *part, const char *state, double value, const char *tween)
10744 {
10745    Edje_Part_Description_Image *img;
10746    unsigned int i;
10747    int search;
10748 
10749    GET_PD_OR_RETURN(EINA_FALSE);
10750 
10751    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10752      return EINA_FALSE;
10753 
10754    img = (Edje_Part_Description_Image *)pd;
10755 
10756    if (!img->image.tweens_count) return EINA_FALSE;
10757 
10758    search = _edje_set_id_find(eed, tween);
10759    if (search < 0)
10760      search = _edje_image_id_find(eed, tween);
10761 
10762    if (search < 0) return EINA_FALSE;
10763 
10764    for (i = 0; i < img->image.tweens_count; ++i)
10765      {
10766         if (img->image.tweens[i]->id == search)
10767           {
10768              img->image.tweens_count--;
10769              free(img->image.tweens[i]);
10770              memmove(img->image.tweens + i,
10771                      img->image.tweens + i + 1,
10772                      sizeof (Edje_Part_Description_Image *) * (img->image.tweens_count - i));
10773              return EINA_TRUE;
10774           }
10775      }
10776    return EINA_FALSE;
10777 }
10778 
10779 EAPI void
edje_edit_state_image_border_get(Evas_Object * obj,const char * part,const char * state,double value,int * l,int * r,int * t,int * b)10780 edje_edit_state_image_border_get(Evas_Object *obj, const char *part, const char *state, double value, int *l, int *r, int *t, int *b)
10781 {
10782    Edje_Part_Description_Image *img;
10783 
10784    GET_PD_OR_RETURN();
10785 
10786    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10787      {
10788         if (l) *l = 0;
10789         if (r) *r = 0;
10790         if (t) *t = 0;
10791         if (b) *b = 0;
10792         return;
10793      }
10794 
10795    img = (Edje_Part_Description_Image *)pd;
10796 
10797    //printf("GET IMAGE_BORDER of state '%s'\n", state);
10798 
10799    if (l) *l = img->image.border.l;
10800    if (r) *r = img->image.border.r;
10801    if (t) *t = img->image.border.t;
10802    if (b) *b = img->image.border.b;
10803 }
10804 
10805 EAPI Eina_Bool
edje_edit_state_image_border_set(Evas_Object * obj,const char * part,const char * state,double value,int l,int r,int t,int b)10806 edje_edit_state_image_border_set(Evas_Object *obj, const char *part, const char *state, double value, int l, int r, int t, int b)
10807 {
10808    Edje_Part_Description_Image *img;
10809 
10810    if ((!obj) || (!part) || (!state))
10811      return EINA_FALSE;
10812    if ((l < -1) || (r < -1) || (t < -1) || (b < -1))
10813      return EINA_FALSE;
10814 
10815    eina_error_set(0);
10816    GET_PD_OR_RETURN(EINA_FALSE);
10817 
10818    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10819      return EINA_FALSE;
10820 
10821    img = (Edje_Part_Description_Image *)pd;
10822 
10823    img->image.border.l = l;
10824    img->image.border.r = r;
10825    img->image.border.t = t;
10826    img->image.border.b = b;
10827 
10828    edje_object_calc_force(obj);
10829    return EINA_TRUE;
10830 }
10831 
10832 EAPI Eina_Bool
edje_edit_state_image_border_scale_get(Evas_Object * obj,const char * part,const char * state,double value)10833 edje_edit_state_image_border_scale_get(Evas_Object *obj, const char *part, const char *state, double value)
10834 {
10835    Edje_Part_Description_Image *img;
10836 
10837    GET_PD_OR_RETURN(EINA_FALSE);
10838 
10839    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10840      return EINA_FALSE;
10841 
10842    img = (Edje_Part_Description_Image *)pd;
10843 
10844    return img->image.border.scale;
10845 }
10846 
10847 EAPI Eina_Bool
edje_edit_state_image_border_scale_set(Evas_Object * obj,const char * part,const char * state,double value,Eina_Bool scale)10848 edje_edit_state_image_border_scale_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool scale)
10849 {
10850    Edje_Part_Description_Image *img;
10851 
10852    GET_PD_OR_RETURN(EINA_FALSE);
10853 
10854    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10855      return EINA_FALSE;
10856 
10857    img = (Edje_Part_Description_Image *)pd;
10858 
10859    img->image.border.scale = scale;
10860 
10861    return EINA_TRUE;
10862 }
10863 
10864 EAPI double
edje_edit_state_image_border_scale_by_get(Evas_Object * obj,const char * part,const char * state,double value)10865 edje_edit_state_image_border_scale_by_get(Evas_Object *obj, const char *part, const char *state, double value)
10866 {
10867    Edje_Part_Description_Image *img;
10868 
10869    GET_PD_OR_RETURN(EINA_FALSE);
10870 
10871    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10872      return EINA_FALSE;
10873 
10874    img = (Edje_Part_Description_Image *)pd;
10875 
10876    return TO_DOUBLE(img->image.border.scale_by);
10877 }
10878 
10879 EAPI Eina_Bool
edje_edit_state_image_border_scale_by_set(Evas_Object * obj,const char * part,const char * state,double value,double border_scale)10880 edje_edit_state_image_border_scale_by_set(Evas_Object *obj, const char *part, const char *state, double value, double border_scale)
10881 {
10882    Edje_Part_Description_Image *img;
10883 
10884    GET_PD_OR_RETURN(EINA_FALSE);
10885 
10886    if (border_scale < 0.0)
10887      return EINA_FALSE;
10888 
10889    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10890      return EINA_FALSE;
10891 
10892    img = (Edje_Part_Description_Image *)pd;
10893 
10894    img->image.border.scale_by = FROM_DOUBLE(border_scale);
10895 
10896    return EINA_TRUE;
10897 }
10898 
10899 EAPI unsigned char
edje_edit_state_image_border_fill_get(Evas_Object * obj,const char * part,const char * state,double value)10900 edje_edit_state_image_border_fill_get(Evas_Object *obj, const char *part, const char *state, double value)
10901 {
10902    Edje_Part_Description_Image *img;
10903 
10904    GET_PD_OR_RETURN(0);
10905 
10906    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10907      return 0;
10908 
10909    img = (Edje_Part_Description_Image *)pd;
10910 
10911    if (img->image.border.no_fill == 2) return 2;
10912    else return !img->image.border.no_fill;
10913 
10914    return 0;
10915 }
10916 
10917 EAPI Eina_Bool
edje_edit_state_image_border_fill_set(Evas_Object * obj,const char * part,const char * state,double value,unsigned char fill)10918 edje_edit_state_image_border_fill_set(Evas_Object *obj, const char *part, const char *state, double value, unsigned char fill)
10919 {
10920    Edje_Part_Description_Image *img;
10921 
10922    if ((!obj) || (!part) || (!state))
10923      return EINA_FALSE;
10924    if (fill > 2)
10925      return EINA_FALSE;
10926 
10927    eina_error_set(0);
10928    GET_PD_OR_RETURN(EINA_FALSE);
10929 
10930    if (rp->part->type != EDJE_PART_TYPE_IMAGE)
10931      return EINA_FALSE;
10932 
10933    img = (Edje_Part_Description_Image *)pd;
10934 
10935    if (fill == 2) img->image.border.no_fill = 2;
10936    else img->image.border.no_fill = !fill;
10937 
10938    edje_object_calc_force(obj);
10939    return EINA_TRUE;
10940 }
10941 
10942 /******************/
10943 /*  PROGRAMS API  */
10944 /******************/
10945 static int
_edje_program_id_find(Edje_Edit * eed,const char * program)10946 _edje_program_id_find(Edje_Edit *eed, const char *program)
10947 {
10948    Edje_Program *epr;
10949    int i;
10950 
10951    for (i = 0; i < eed->base->collection->patterns.table_programs_size; i++)
10952      {
10953         epr = eed->base->collection->patterns.table_programs[i];
10954         if (epr->name && !strcmp(epr->name, program))
10955           return epr->id;
10956      }
10957    return -1;
10958 }
10959 
10960 static Edje_Program *
_edje_program_get_byname(Evas_Object * obj,const char * prog_name)10961 _edje_program_get_byname(Evas_Object *obj, const char *prog_name)
10962 {
10963    Edje_Program *epr;
10964    int i;
10965 
10966    GET_ED_OR_RETURN(NULL);
10967 
10968    if (!prog_name) return NULL;
10969 
10970    for (i = 0; i < ed->collection->patterns.table_programs_size; i++)
10971      {
10972         epr = ed->collection->patterns.table_programs[i];
10973         if ((epr->name) && (strcmp(epr->name, prog_name) == 0))
10974           return epr;
10975      }
10976    return NULL;
10977 }
10978 
10979 EAPI Eina_List *
edje_edit_programs_list_get(Evas_Object * obj)10980 edje_edit_programs_list_get(Evas_Object *obj)
10981 {
10982    Eina_List *progs = NULL;
10983    int i;
10984 
10985    GET_ED_OR_RETURN(NULL);
10986 
10987    //printf("EE: Found %d programs\n", ed->table_programs_size);
10988 
10989    for (i = 0; i < ed->collection->patterns.table_programs_size; i++)
10990      {
10991         Edje_Program *epr;
10992 
10993         epr = ed->collection->patterns.table_programs[i];
10994         /* XXX: bad, we miss programs this way, but since you can't access
10995          * them in any way without a name, better ignore them.  */
10996         if (!epr->name) continue;
10997         progs = eina_list_append(progs, eina_stringshare_add(epr->name));
10998      }
10999 
11000    return progs;
11001 }
11002 
11003 EAPI Eina_Bool
edje_edit_program_add(Evas_Object * obj,const char * name)11004 edje_edit_program_add(Evas_Object *obj, const char *name)
11005 {
11006    Edje_Program *epr;
11007 
11008    GET_ED_OR_RETURN(EINA_FALSE);
11009 
11010    //printf("ADD PROGRAM [new name: %s]\n", name);
11011 
11012    //Check if program already exists
11013    if (_edje_program_get_byname(obj, name))
11014      return EINA_FALSE;
11015 
11016    //Alloc Edje_Program or return
11017    epr = _alloc(sizeof(Edje_Program));
11018    if (!epr) return EINA_FALSE;
11019 
11020    //Add program to group
11021    // pc = ed->collection;
11022 
11023    /* By default, source and signal are empty, so they fill in nocmp category */
11024    ed->collection->programs.nocmp = realloc(ed->collection->programs.nocmp,
11025                                             sizeof (Edje_Program *) * (ed->collection->programs.nocmp_count + 1));
11026    ed->collection->programs.nocmp[ed->collection->programs.nocmp_count++] = epr;
11027 
11028    //Init Edje_Program
11029    epr->id = ed->collection->patterns.table_programs_size;
11030    epr->name = eina_stringshare_add(name);
11031    epr->signal = NULL;
11032    epr->source = NULL;
11033    epr->filter.part = NULL;
11034    epr->filter.state = NULL;
11035    epr->in.from = 0.0;
11036    epr->in.range = 0.0;
11037    epr->action = 0;
11038    epr->seat = NULL;
11039    epr->state = NULL;
11040    epr->value = 0.0;
11041    epr->state2 = NULL;
11042    epr->value2 = 0.0;
11043    epr->tween.mode = 1;
11044    epr->tween.time = ZERO;
11045    epr->targets = NULL;
11046    epr->after = NULL;
11047    epr->sample_name = NULL;
11048    epr->speed = 1.0;
11049    epr->channel = EDJE_CHANNEL_EFFECT;
11050    epr->tone_name = NULL;
11051    epr->duration = 0.1;
11052 
11053    //Update table_programs
11054    ed->collection->patterns.table_programs_size++;
11055    ed->collection->patterns.table_programs = realloc(ed->collection->patterns.table_programs,
11056                                                      sizeof(Edje_Program *) * ed->collection->patterns.table_programs_size);
11057    ed->collection->patterns.table_programs[epr->id % ed->collection->patterns.table_programs_size] = epr;
11058 
11059    //Update patterns
11060    _edje_programs_patterns_clean(ed->collection);
11061    _edje_programs_patterns_init(ed->collection);
11062 
11063    return EINA_TRUE;
11064 }
11065 
11066 EAPI Eina_Bool
edje_edit_program_del(Evas_Object * obj,const char * prog)11067 edje_edit_program_del(Evas_Object *obj, const char *prog)
11068 {
11069    Eina_List *l, *l_next;
11070    Edje_Program_Target *prt;
11071    Edje_Program_After *pa;
11072    Edje_Program *p;
11073    Program_Script *ps, *old_ps;
11074    int id, i;
11075    int old_id = -1;
11076 
11077    GET_EED_OR_RETURN(EINA_FALSE);
11078    GET_ED_OR_RETURN(EINA_FALSE);
11079    GET_EPR_OR_RETURN(EINA_FALSE);
11080 
11081    //pc = ed->collection;
11082 
11083    //Remove program from programs list
11084    id = epr->id;
11085    _edje_program_remove(ed->collection, epr);
11086 
11087    /* fix table program */
11088    if (epr->id != ed->collection->patterns.table_programs_size - 1)
11089      {
11090         /* If the removed program is not the last in the list/table,
11091          * put the last one in its place and update references to it later */
11092         ed->collection->patterns.table_programs[epr->id] = ed->collection->patterns.table_programs[ed->collection->patterns.table_programs_size - 1];
11093         old_id = ed->collection->patterns.table_programs_size - 1;
11094         ed->collection->patterns.table_programs[epr->id]->id = epr->id;
11095      }
11096 
11097    ps = eina_hash_find(eed->program_scripts, &id);
11098    old_ps = eina_hash_find(eed->program_scripts, &old_id);
11099    if (old_ps)
11100      {
11101         if (!ps)
11102           {
11103              ps = _alloc(sizeof(Program_Script));
11104              ps->id = id;
11105              eina_hash_add(eed->program_scripts, &id, ps);
11106           }
11107         else
11108           {
11109              free(ps->code);
11110              free(ps->processed);
11111              ps->processed = NULL;
11112              ps->delete_me = EINA_FALSE;
11113           }
11114         ps->code = old_ps->code;
11115         old_ps->code = NULL;
11116         free(old_ps->processed);
11117         old_ps->processed = NULL;
11118         ps->dirty = EINA_TRUE;
11119         old_ps->dirty = EINA_FALSE;
11120         old_ps->delete_me = EINA_TRUE;
11121      }
11122    else if (ps)
11123      {
11124         ps->dirty = EINA_FALSE;
11125         ps->delete_me = EINA_TRUE;
11126      }
11127 
11128    //Free Edje_Program
11129    _edje_if_string_free(ed, &epr->name);
11130    _edje_if_string_free(ed, &epr->signal);
11131    _edje_if_string_free(ed, &epr->source);
11132    _edje_if_string_free(ed, &epr->filter.part);
11133    _edje_if_string_free(ed, &epr->filter.state);
11134    _edje_if_string_free(ed, &epr->seat);
11135    _edje_if_string_free(ed, &epr->state);
11136    _edje_if_string_free(ed, &epr->state2);
11137    _edje_if_string_free(ed, &epr->sample_name);
11138    _edje_if_string_free(ed, &epr->tone_name);
11139 
11140    EINA_LIST_FREE(epr->targets, prt)
11141      free(prt);
11142    EINA_LIST_FREE(epr->after, pa)
11143      free(pa);
11144    free(epr);
11145 
11146    ed->collection->patterns.table_programs_size--;
11147    ed->collection->patterns.table_programs = realloc(ed->collection->patterns.table_programs,
11148                                                      sizeof(Edje_Program *) * ed->collection->patterns.table_programs_size);
11149 
11150    //We also update all other programs that point to old_id and id
11151    for (i = 0; i < ed->collection->patterns.table_programs_size; i++)
11152      {
11153         p = ed->collection->patterns.table_programs[i];
11154 
11155         /* check in afters */
11156         EINA_LIST_FOREACH_SAFE(p->after, l, l_next, pa)
11157           {
11158              if (pa->id == old_id)
11159                pa->id = id;
11160              else if (pa->id == id)
11161                {
11162                   p->after = eina_list_remove_list(p->after, l);
11163                   free(pa);
11164                }
11165           }
11166         /* check in targets */
11167         if (p->action == EDJE_ACTION_TYPE_ACTION_STOP)
11168           {
11169              Edje_Program_Target *pt;
11170 
11171              EINA_LIST_FOREACH_SAFE(p->targets, l, l_next, pt)
11172                {
11173                   if (pt->id == old_id)
11174                     pt->id = id;
11175                   else if (pt->id == id)
11176                     {
11177                        p->targets = eina_list_remove_list(p->targets, l);
11178                        free(pt);
11179                     }
11180                }
11181           }
11182      }
11183 
11184    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
11185 
11186    return EINA_TRUE;
11187 }
11188 
11189 EAPI Eina_Bool
edje_edit_program_exist(Evas_Object * obj,const char * prog)11190 edje_edit_program_exist(Evas_Object *obj, const char *prog)
11191 {
11192    GET_EPR_OR_RETURN(EINA_FALSE);
11193 
11194    return EINA_TRUE;
11195 }
11196 
11197 EAPI Eina_Bool
edje_edit_program_run(Evas_Object * obj,const char * prog)11198 edje_edit_program_run(Evas_Object *obj, const char *prog)
11199 {
11200    GET_ED_OR_RETURN(EINA_FALSE);
11201    GET_EPR_OR_RETURN(EINA_FALSE);
11202 
11203    _edje_program_run(ed, epr, 0, "", "", NULL);
11204    return EINA_TRUE;
11205 }
11206 
11207 EAPI Eina_Bool
edje_edit_program_stop_all(Evas_Object * obj)11208 edje_edit_program_stop_all(Evas_Object *obj)
11209 {
11210    GET_ED_OR_RETURN(EINA_FALSE);
11211 
11212    Eina_List *l, *ln;
11213    Edje_Running_Program *runp;
11214 
11215    EINA_LIST_FOREACH_SAFE(ed->actions, l, ln, runp)
11216      _edje_program_end(ed, runp);
11217 
11218    return EINA_TRUE;
11219 }
11220 
11221 EAPI Eina_Bool
edje_edit_program_transition_state_set(Evas_Object * obj,const char * prog,double position)11222 edje_edit_program_transition_state_set(Evas_Object *obj, const char *prog, double position)
11223 {
11224    Edje_Program_Target *pt;
11225    Edje_Real_Part *rp;
11226    Eina_List *l;
11227 
11228    GET_ED_OR_RETURN(EINA_FALSE);
11229    GET_EPR_OR_RETURN(EINA_FALSE);
11230    if (position < 0 || position > 1) return EINA_FALSE;
11231    if (epr->action != EDJE_ACTION_TYPE_STATE_SET) return EINA_FALSE;
11232 
11233    EINA_LIST_FOREACH(epr->targets, l, pt)
11234      {
11235         if (pt->id >= 0)
11236           {
11237              rp = ed->table_parts[pt->id % ed->table_parts_size];
11238              if (rp)
11239                {
11240                   _edje_part_description_apply(ed, rp,
11241                                                rp->param1.description->state.name,
11242                                                rp->param1.description->state.value,
11243                                                epr->state,
11244                                                epr->value);
11245                   _edje_part_pos_set(ed, rp,
11246                                      epr->tween.mode, position,
11247                                      epr->tween.v1,
11248                                      epr->tween.v2,
11249                                      epr->tween.v3,
11250                                      epr->tween.v4);
11251                }
11252           }
11253      }
11254    _edje_recalc(ed);
11255 
11256    return EINA_TRUE;
11257 }
11258 
11259 EAPI Eina_Bool
edje_edit_program_name_set(Evas_Object * obj,const char * prog,const char * new_name)11260 edje_edit_program_name_set(Evas_Object *obj, const char *prog, const char *new_name)
11261 {
11262    GET_EED_OR_RETURN(EINA_FALSE);
11263    GET_ED_OR_RETURN(EINA_FALSE);
11264    GET_EPR_OR_RETURN(EINA_FALSE);
11265 
11266    if (!new_name) return EINA_FALSE;
11267 
11268    if (!strcmp(prog, new_name)) return EINA_TRUE;
11269 
11270    if (_edje_program_get_byname(obj, new_name)) return EINA_FALSE;
11271 
11272    //printf("SET NAME for program: %s [new name: %s]\n", prog, new_name);
11273 
11274    _edje_if_string_replace(ed, &epr->name, new_name);
11275 
11276    _edje_edit_flag_script_dirty(eed, EINA_TRUE);
11277 
11278    return EINA_TRUE;
11279 }
11280 
11281 EAPI const char *
edje_edit_program_source_get(Evas_Object * obj,const char * prog)11282 edje_edit_program_source_get(Evas_Object *obj, const char *prog)
11283 {
11284    GET_EPR_OR_RETURN(NULL);
11285 
11286    if (!epr->source) return NULL;
11287    //printf("GET SOURCE for program: %s [%s]\n", prog, epr->source);
11288    return eina_stringshare_add(epr->source);
11289 }
11290 
11291 EAPI Eina_Bool
edje_edit_program_source_set(Evas_Object * obj,const char * prog,const char * source)11292 edje_edit_program_source_set(Evas_Object *obj, const char *prog, const char *source)
11293 {
11294    GET_ED_OR_RETURN(EINA_FALSE);
11295    GET_EPR_OR_RETURN(EINA_FALSE);
11296 
11297    /* Remove from program array */
11298    _edje_program_remove(ed->collection, epr);
11299 
11300    /* Insert it back */
11301    _edje_if_string_replace(ed, &epr->source, source);
11302    _edje_program_insert(ed->collection, epr);
11303 
11304    //Update patterns
11305    _edje_programs_patterns_clean(ed->collection);
11306    _edje_programs_patterns_init(ed->collection);
11307 
11308    return EINA_TRUE;
11309 }
11310 
11311 EAPI const char *
edje_edit_program_sample_name_get(Evas_Object * obj,const char * prog)11312 edje_edit_program_sample_name_get(Evas_Object *obj, const char *prog)
11313 {
11314    GET_EPR_OR_RETURN(NULL);
11315 
11316    if (!epr->sample_name) return NULL;
11317    return eina_stringshare_add(epr->sample_name);
11318 }
11319 
11320 EAPI Eina_Bool
edje_edit_program_sample_name_set(Evas_Object * obj,const char * prog,const char * name)11321 edje_edit_program_sample_name_set(Evas_Object *obj, const char *prog, const char *name)
11322 {
11323    GET_ED_OR_RETURN(EINA_FALSE);
11324    GET_EPR_OR_RETURN(EINA_FALSE);
11325 
11326    if (!name) return EINA_FALSE;
11327 
11328    _edje_if_string_replace(ed, &epr->sample_name, name);
11329 
11330    return EINA_TRUE;
11331 }
11332 
11333 EAPI const char *
edje_edit_program_tone_name_get(Evas_Object * obj,const char * prog)11334 edje_edit_program_tone_name_get(Evas_Object *obj, const char *prog)
11335 {
11336    GET_EPR_OR_RETURN(NULL);
11337 
11338    if (!epr->tone_name) return NULL;
11339    return eina_stringshare_add(epr->tone_name);
11340 }
11341 
11342 EAPI Eina_Bool
edje_edit_program_tone_name_set(Evas_Object * obj,const char * prog,const char * name)11343 edje_edit_program_tone_name_set(Evas_Object *obj, const char *prog, const char *name)
11344 {
11345    GET_ED_OR_RETURN(EINA_FALSE);
11346    GET_EPR_OR_RETURN(EINA_FALSE);
11347 
11348    if (!name) return EINA_FALSE;
11349 
11350    _edje_if_string_replace(ed, &epr->tone_name, name);
11351 
11352    return EINA_TRUE;
11353 }
11354 
11355 EAPI double
edje_edit_program_sample_speed_get(Evas_Object * obj,const char * prog)11356 edje_edit_program_sample_speed_get(Evas_Object *obj, const char *prog)
11357 {
11358    GET_EPR_OR_RETURN(-1);
11359 
11360    return epr->speed;
11361 }
11362 
11363 EAPI Eina_Bool
edje_edit_program_sample_speed_set(Evas_Object * obj,const char * prog,double speed)11364 edje_edit_program_sample_speed_set(Evas_Object *obj, const char *prog, double speed)
11365 {
11366    GET_EPR_OR_RETURN(EINA_FALSE);
11367 
11368    if (speed < 0) return EINA_FALSE;
11369 
11370    epr->speed = speed;
11371 
11372    return EINA_TRUE;
11373 }
11374 
11375 EAPI double
edje_edit_program_tone_duration_get(Evas_Object * obj,const char * prog)11376 edje_edit_program_tone_duration_get(Evas_Object *obj, const char *prog)
11377 {
11378    GET_EPR_OR_RETURN(-1);
11379 
11380    return epr->duration;
11381 }
11382 
11383 EAPI Eina_Bool
edje_edit_program_tone_duration_set(Evas_Object * obj,const char * prog,double duration)11384 edje_edit_program_tone_duration_set(Evas_Object *obj, const char *prog, double duration)
11385 {
11386    GET_EPR_OR_RETURN(EINA_FALSE);
11387 
11388    if (duration < 0) return EINA_FALSE;
11389 
11390    epr->duration = duration;
11391 
11392    return EINA_TRUE;
11393 }
11394 
11395 EAPI unsigned char
edje_edit_program_channel_get(Evas_Object * obj,const char * prog)11396 edje_edit_program_channel_get(Evas_Object *obj, const char *prog)
11397 {
11398    GET_EPR_OR_RETURN(0);
11399 
11400    return epr->channel;
11401 }
11402 
11403 EAPI Eina_Bool
edje_edit_program_channel_set(Evas_Object * obj,const char * prog,Edje_Channel channel)11404 edje_edit_program_channel_set(Evas_Object *obj, const char *prog, Edje_Channel channel)
11405 {
11406    GET_EPR_OR_RETURN(EINA_FALSE);
11407 
11408    epr->channel = channel;
11409 
11410    return EINA_TRUE;
11411 }
11412 
11413 EAPI const char *
edje_edit_program_filter_part_get(Evas_Object * obj,const char * prog)11414 edje_edit_program_filter_part_get(Evas_Object *obj, const char *prog)
11415 {
11416    GET_EPR_OR_RETURN(NULL);
11417 
11418    if (!epr->filter.part) return NULL;
11419    return eina_stringshare_add(epr->filter.part);
11420 }
11421 
11422 EAPI Eina_Bool
edje_edit_program_filter_part_set(Evas_Object * obj,const char * prog,const char * filter_part)11423 edje_edit_program_filter_part_set(Evas_Object *obj, const char *prog, const char *filter_part)
11424 {
11425    GET_ED_OR_RETURN(EINA_FALSE);
11426    GET_EPR_OR_RETURN(EINA_FALSE);
11427 
11428    _edje_if_string_replace(ed, &epr->filter.part, filter_part);
11429 
11430    return EINA_TRUE;
11431 }
11432 
11433 EAPI const char *
edje_edit_program_filter_state_get(Evas_Object * obj,const char * prog)11434 edje_edit_program_filter_state_get(Evas_Object *obj, const char *prog)
11435 {
11436    GET_EPR_OR_RETURN(NULL);
11437 
11438    if (!epr->filter.state) return NULL;
11439    return eina_stringshare_add(epr->filter.state);
11440 }
11441 
11442 EAPI Eina_Bool
edje_edit_program_filter_state_set(Evas_Object * obj,const char * prog,const char * filter_state)11443 edje_edit_program_filter_state_set(Evas_Object *obj, const char *prog, const char *filter_state)
11444 {
11445    GET_ED_OR_RETURN(EINA_FALSE);
11446    GET_EPR_OR_RETURN(EINA_FALSE);
11447 
11448    _edje_if_string_replace(ed, &epr->filter.state, filter_state);
11449 
11450    return EINA_TRUE;
11451 }
11452 
11453 EAPI const char *
edje_edit_program_signal_get(Evas_Object * obj,const char * prog)11454 edje_edit_program_signal_get(Evas_Object *obj, const char *prog)
11455 {
11456    GET_EPR_OR_RETURN(NULL);
11457 
11458    if (!epr->signal) return NULL;
11459    //printf("GET SIGNAL for program: %s [%s]\n", prog, epr->signal);
11460    return eina_stringshare_add(epr->signal);
11461 }
11462 
11463 EAPI Eina_Bool
edje_edit_program_signal_set(Evas_Object * obj,const char * prog,const char * sig)11464 edje_edit_program_signal_set(Evas_Object *obj, const char *prog, const char *sig)
11465 {
11466    GET_ED_OR_RETURN(EINA_FALSE);
11467    GET_EPR_OR_RETURN(EINA_FALSE);
11468 
11469    /* Remove from program array */
11470    _edje_program_remove(ed->collection, epr);
11471 
11472    /* Insert it back */
11473    _edje_if_string_replace(ed, &epr->signal, sig);
11474    _edje_program_insert(ed->collection, epr);
11475 
11476    //Update patterns
11477    _edje_programs_patterns_clean(ed->collection);
11478    _edje_programs_patterns_init(ed->collection);
11479 
11480    return EINA_TRUE;
11481 }
11482 
11483 EAPI const char *
edje_edit_program_state_get(Evas_Object * obj,const char * prog)11484 edje_edit_program_state_get(Evas_Object *obj, const char *prog)
11485 {
11486    GET_EPR_OR_RETURN(NULL);
11487 
11488    if (!epr->state) return NULL;
11489    //printf("GET STATE for program: %s [%s %.2f]\n", prog, epr->state, epr->value);
11490    return eina_stringshare_add(epr->state);
11491 }
11492 
11493 EAPI Eina_Bool
edje_edit_program_state_set(Evas_Object * obj,const char * prog,const char * state)11494 edje_edit_program_state_set(Evas_Object *obj, const char *prog, const char *state)
11495 {
11496    GET_ED_OR_RETURN(EINA_FALSE);
11497    GET_EPR_OR_RETURN(EINA_FALSE);
11498 
11499    //printf("SET STATE for program: %s\n", prog);
11500 
11501    _edje_if_string_replace(ed, &epr->state, state);
11502 
11503    return EINA_TRUE;
11504 }
11505 
11506 EAPI const char *
edje_edit_program_state2_get(Evas_Object * obj,const char * prog)11507 edje_edit_program_state2_get(Evas_Object *obj, const char *prog)
11508 {
11509    GET_EPR_OR_RETURN(NULL);
11510 
11511    if (!epr->state2) return NULL;
11512    //printf("GET STATE2 for program: %s [%s %.2f]\n", prog, epr->state2, epr->value2);
11513    return eina_stringshare_add(epr->state2);
11514 }
11515 
11516 EAPI Eina_Bool
edje_edit_program_state2_set(Evas_Object * obj,const char * prog,const char * state2)11517 edje_edit_program_state2_set(Evas_Object *obj, const char *prog, const char *state2)
11518 {
11519    GET_ED_OR_RETURN(EINA_FALSE);
11520    GET_EPR_OR_RETURN(EINA_FALSE);
11521 
11522    //printf("SET STATE2 for program: %s\n", prog);
11523 
11524    _edje_if_string_replace(ed, &epr->state2, state2);
11525 
11526    return EINA_TRUE;
11527 }
11528 
11529 EAPI double
edje_edit_program_value_get(Evas_Object * obj,const char * prog)11530 edje_edit_program_value_get(Evas_Object *obj, const char *prog)
11531 {
11532    GET_EPR_OR_RETURN(-1);
11533 
11534    //printf("GET VALUE for program: %s [%s %.2f]\n", prog, epr->state, epr->value);
11535    return epr->value;
11536 }
11537 
11538 EAPI Eina_Bool
edje_edit_program_value_set(Evas_Object * obj,const char * prog,double value)11539 edje_edit_program_value_set(Evas_Object *obj, const char *prog, double value)
11540 {
11541    GET_EPR_OR_RETURN(EINA_FALSE);
11542 
11543    //printf("SET VALUE for program: %s [%.2f]\n", prog, value);
11544    epr->value = value;
11545    return EINA_TRUE;
11546 }
11547 
11548 EAPI double
edje_edit_program_value2_get(Evas_Object * obj,const char * prog)11549 edje_edit_program_value2_get(Evas_Object *obj, const char *prog)
11550 {
11551    GET_EPR_OR_RETURN(-1);
11552 
11553    //printf("GET VALUE2 for program: %s [%s %.2f]\n", prog, epr->state2, epr->value2);
11554    return epr->value2;
11555 }
11556 
11557 EAPI Eina_Bool
edje_edit_program_value2_set(Evas_Object * obj,const char * prog,double value)11558 edje_edit_program_value2_set(Evas_Object *obj, const char *prog, double value)
11559 {
11560    GET_EPR_OR_RETURN(EINA_FALSE);
11561 
11562    //printf("SET VALUE for program: %s [%.2f]\n", prog, value);
11563    epr->value2 = value;
11564    return EINA_TRUE;
11565 }
11566 
11567 EAPI double
edje_edit_program_in_from_get(Evas_Object * obj,const char * prog)11568 edje_edit_program_in_from_get(Evas_Object *obj, const char *prog)
11569 {
11570    GET_EPR_OR_RETURN(0);
11571 
11572    //printf("GET IN.FROM for program: %s [%f]\n", prog, epr->in.from);
11573    return epr->in.from;
11574 }
11575 
11576 EAPI Eina_Bool
edje_edit_program_in_from_set(Evas_Object * obj,const char * prog,double seconds)11577 edje_edit_program_in_from_set(Evas_Object *obj, const char *prog, double seconds)
11578 {
11579    GET_EPR_OR_RETURN(EINA_FALSE);
11580 
11581    //printf("SET IN.FROM for program: %s [%f]\n", prog, epr->in.from);
11582    epr->in.from = seconds;
11583    return EINA_TRUE;
11584 }
11585 
11586 EAPI double
edje_edit_program_in_range_get(Evas_Object * obj,const char * prog)11587 edje_edit_program_in_range_get(Evas_Object *obj, const char *prog)
11588 {
11589    GET_EPR_OR_RETURN(0);
11590 
11591    //printf("GET IN.RANGE for program: %s [%f]\n", prog, epr->in.range);
11592    return epr->in.range;
11593 }
11594 
11595 EAPI Eina_Bool
edje_edit_program_in_range_set(Evas_Object * obj,const char * prog,double seconds)11596 edje_edit_program_in_range_set(Evas_Object *obj, const char *prog, double seconds)
11597 {
11598    GET_EPR_OR_RETURN(EINA_FALSE);
11599 
11600    //printf("SET IN.RANGE for program: %s [%f]\n", prog, epr->in.range);
11601    epr->in.range = seconds;
11602    return EINA_TRUE;
11603 }
11604 
11605 EAPI Edje_Tween_Mode
edje_edit_program_transition_get(Evas_Object * obj,const char * prog)11606 edje_edit_program_transition_get(Evas_Object *obj, const char *prog)
11607 {
11608    GET_EPR_OR_RETURN(-1);
11609 
11610    //printf("GET TRANSITION for program: %s [%d]\n", prog, epr->tween.mode);
11611    return epr->tween.mode;
11612 }
11613 
11614 EAPI Eina_Bool
edje_edit_program_transition_set(Evas_Object * obj,const char * prog,Edje_Tween_Mode transition)11615 edje_edit_program_transition_set(Evas_Object *obj, const char *prog, Edje_Tween_Mode transition)
11616 {
11617    GET_EPR_OR_RETURN(EINA_FALSE);
11618 
11619    //printf("GET TRANSITION for program: %s [%d]\n", prog, epr->tween.mode);
11620    epr->tween.mode = transition;
11621    return EINA_TRUE;
11622 }
11623 
11624 #define FUNC_PROGRAM_TRANSITION_VALUE(Num)                                                         \
11625   EAPI double                                                                                      \
11626   edje_edit_program_transition_value##Num##_get(Evas_Object * obj, const char *prog)               \
11627   {                                                                                                \
11628      eina_error_set(0);                                                                            \
11629                                                                                                    \
11630      GET_EPR_OR_RETURN(-1);                                                                        \
11631                                                                                                    \
11632      return TO_DOUBLE(epr->tween.v##Num);                                                          \
11633   }                                                                                                \
11634   EAPI Eina_Bool                                                                                   \
11635   edje_edit_program_transition_value##Num##_set(Evas_Object * obj, const char *prog, double value) \
11636   {                                                                                                \
11637      eina_error_set(0);                                                                            \
11638                                                                                                    \
11639      GET_EPR_OR_RETURN(EINA_FALSE);                                                                \
11640                                                                                                    \
11641      epr->tween.v##Num = FROM_DOUBLE(value);                                                       \
11642      return EINA_TRUE;                                                                             \
11643   }
11644 
11645 FUNC_PROGRAM_TRANSITION_VALUE(1)
11646 FUNC_PROGRAM_TRANSITION_VALUE(2)
11647 FUNC_PROGRAM_TRANSITION_VALUE(3)
11648 FUNC_PROGRAM_TRANSITION_VALUE(4)
11649 
11650 #undef FUNC_PROGRAM_TRANSITION_VALUE
11651 
11652 EAPI double
edje_edit_program_transition_time_get(Evas_Object * obj,const char * prog)11653 edje_edit_program_transition_time_get(Evas_Object *obj, const char *prog)
11654 {
11655    GET_EPR_OR_RETURN(-1);
11656 
11657    //printf("GET TRANSITION_TIME for program: %s [%.4f]\n", prog, epr->tween.time);
11658    return TO_DOUBLE(epr->tween.time);
11659 }
11660 
11661 EAPI Eina_Bool
edje_edit_program_transition_time_set(Evas_Object * obj,const char * prog,double seconds)11662 edje_edit_program_transition_time_set(Evas_Object *obj, const char *prog, double seconds)
11663 {
11664    GET_EPR_OR_RETURN(EINA_FALSE);
11665 
11666    //printf("GET TRANSITION_TIME for program: %s [%.4f]\n", prog, epr->tween.time);
11667    epr->tween.time = FROM_DOUBLE(seconds);
11668    return EINA_TRUE;
11669 }
11670 
11671 EAPI Edje_Action_Type
edje_edit_program_action_get(Evas_Object * obj,const char * prog)11672 edje_edit_program_action_get(Evas_Object *obj, const char *prog)
11673 {
11674    GET_EPR_OR_RETURN(-1);
11675 
11676    //printf("GET ACTION for program: %s [%d]\n", prog, epr->action);
11677    return epr->action;
11678 }
11679 
11680 EAPI Eina_Bool
edje_edit_program_action_set(Evas_Object * obj,const char * prog,Edje_Action_Type action)11681 edje_edit_program_action_set(Evas_Object *obj, const char *prog, Edje_Action_Type action)
11682 {
11683    Program_Script *ps;
11684 
11685    GET_EED_OR_RETURN(EINA_FALSE);
11686    GET_EPR_OR_RETURN(EINA_FALSE);
11687 
11688    //printf("SET ACTION for program: %s [%d]\n", prog, action);
11689    if (action >= EDJE_ACTION_TYPE_LAST) return EINA_FALSE;
11690 
11691    if ((Edje_Action_Type)epr->action == action)
11692      return EINA_TRUE;
11693 
11694    if (action == EDJE_ACTION_TYPE_SCRIPT)
11695      {
11696         ps = eina_hash_find(eed->program_scripts, &epr->id);
11697         if (!ps)
11698           {
11699              ps = _alloc(sizeof(Program_Script));
11700              if (!ps)
11701                return EINA_FALSE;
11702           }
11703         ps->id = epr->id;
11704         ps->code = strdup("");
11705         ps->dirty = EINA_TRUE;
11706         ps->delete_me = EINA_FALSE;
11707         eina_hash_set(eed->program_scripts, &ps->id, ps);
11708         _edje_edit_flag_script_dirty(eed, EINA_FALSE);
11709      }
11710    if (epr->action == EDJE_ACTION_TYPE_SCRIPT)
11711      {
11712         ps = eina_hash_find(eed->program_scripts, &epr->id);
11713         if (ps)
11714           {
11715              free(ps->code);
11716              free(ps->processed);
11717              ps->code = ps->processed = NULL;
11718              ps->dirty = EINA_FALSE;
11719              ps->delete_me = EINA_TRUE;
11720              _edje_edit_flag_script_dirty(eed, EINA_FALSE);
11721           }
11722      }
11723 
11724    switch (action)
11725      {
11726       case EDJE_ACTION_TYPE_STATE_SET:
11727       case EDJE_ACTION_TYPE_SIGNAL_EMIT:
11728       case EDJE_ACTION_TYPE_DRAG_VAL_SET:
11729       case EDJE_ACTION_TYPE_DRAG_VAL_STEP:
11730       case EDJE_ACTION_TYPE_DRAG_VAL_PAGE:
11731       case EDJE_ACTION_TYPE_FOCUS_SET:
11732       case EDJE_ACTION_TYPE_FOCUS_OBJECT:
11733 #ifdef HAVE_EPHYSICS
11734       case EDJE_ACTION_TYPE_PHYSICS_FORCES_CLEAR:
11735       case EDJE_ACTION_TYPE_PHYSICS_STOP:
11736       case EDJE_ACTION_TYPE_PHYSICS_ROT_SET:
11737 #endif
11738         /*This actions have part as a target so targets list can be leaved untouched
11739            if it was not list of programs (EDJE_ACTION_TYPE_ACTION_STOP) */
11740         if (epr->action == EDJE_ACTION_TYPE_ACTION_STOP)
11741           edje_edit_program_targets_clear(obj, prog);
11742         break;
11743 
11744       case EDJE_ACTION_TYPE_ACTION_STOP:
11745       /*this action needs programs as targets*/
11746       default:
11747         /*other actions do not need targets so we need to delete them all */
11748         edje_edit_program_targets_clear(obj, prog);
11749      }
11750 
11751    epr->action = action;
11752    return EINA_TRUE;
11753 }
11754 
11755 static Eina_List *
_edje_program_targets_get(Evas_Object * obj,Edje_Program * epr)11756 _edje_program_targets_get(Evas_Object *obj, Edje_Program *epr)
11757 {
11758    Eina_List *l, *targets = NULL;
11759    Edje_Program_Target *t;
11760 
11761    GET_ED_OR_RETURN(NULL);
11762 
11763    EINA_LIST_FOREACH(epr->targets, l, t)
11764      {
11765         switch (epr->action)
11766           {
11767            /*action types, that does not support targets*/
11768            case EDJE_ACTION_TYPE_SCRIPT:
11769            case EDJE_ACTION_TYPE_SOUND_SAMPLE:
11770            case EDJE_ACTION_TYPE_SOUND_TONE:
11771            case EDJE_ACTION_TYPE_VIBRATION_SAMPLE:
11772            case EDJE_ACTION_TYPE_PARAM_COPY:
11773            case EDJE_ACTION_TYPE_PARAM_SET:
11774 #ifdef HAVE_EPHYSICS
11775            case EDJE_ACTION_TYPE_PHYSICS_IMPULSE:
11776            case EDJE_ACTION_TYPE_PHYSICS_TORQUE_IMPULSE:
11777            case EDJE_ACTION_TYPE_PHYSICS_FORCE:
11778            case EDJE_ACTION_TYPE_PHYSICS_TORQUE:
11779            case EDJE_ACTION_TYPE_PHYSICS_VEL_SET:
11780            case EDJE_ACTION_TYPE_PHYSICS_ANG_VEL_SET:
11781 #endif
11782            break;
11783 
11784            /* the target is a program */
11785            case EDJE_ACTION_TYPE_ACTION_STOP:
11786              {
11787                Edje_Program *p = NULL;
11788 
11789                p = ed->collection->patterns.table_programs[t->id % ed->collection->patterns.table_programs_size];
11790                if (p && p->name)
11791                  targets = eina_list_append(targets,
11792                                             eina_stringshare_add(p->name));
11793              }
11794            break;
11795 
11796            /* the target is a part */
11797            case EDJE_ACTION_TYPE_SIGNAL_EMIT:
11798            case EDJE_ACTION_TYPE_STATE_SET:
11799            case EDJE_ACTION_TYPE_DRAG_VAL_SET:
11800            case EDJE_ACTION_TYPE_DRAG_VAL_STEP:
11801            case EDJE_ACTION_TYPE_DRAG_VAL_PAGE:
11802            case EDJE_ACTION_TYPE_FOCUS_SET:
11803            case EDJE_ACTION_TYPE_FOCUS_OBJECT:
11804 #ifdef HAVE_EPHYSICS
11805            case EDJE_ACTION_TYPE_PHYSICS_FORCES_CLEAR:
11806            case EDJE_ACTION_TYPE_PHYSICS_STOP:
11807            case EDJE_ACTION_TYPE_PHYSICS_ROT_SET:
11808 #endif
11809              {
11810                 Edje_Real_Part *p = NULL;
11811                 p = ed->table_parts[t->id % ed->table_parts_size];
11812                 if (p && p->part && p->part->name)
11813                   targets = eina_list_append(targets,
11814                                              eina_stringshare_add(p->part->name));
11815              }
11816            break;
11817           }
11818      }
11819    return targets;
11820 }
11821 
11822 EAPI Eina_List *
edje_edit_program_targets_get(Evas_Object * obj,const char * prog)11823 edje_edit_program_targets_get(Evas_Object *obj, const char *prog)
11824 {
11825    GET_EPR_OR_RETURN(NULL);
11826 
11827    return _edje_program_targets_get(obj, epr);
11828 }
11829 
11830 EAPI Eina_Bool
edje_edit_program_targets_clear(Evas_Object * obj,const char * prog)11831 edje_edit_program_targets_clear(Evas_Object *obj, const char *prog)
11832 {
11833    GET_EPR_OR_RETURN(EINA_FALSE);
11834 
11835    while (epr->targets)
11836      {
11837         Edje_Program_Target *prt;
11838 
11839         prt = eina_list_data_get(epr->targets);
11840         epr->targets = eina_list_remove_list(epr->targets, epr->targets);
11841         free(prt);
11842      }
11843 
11844    return EINA_TRUE;
11845 }
11846 
11847 static int
_program_target_id_get(Evas_Object * obj,Edje * ed,Edje_Action_Type action,const char * target)11848 _program_target_id_get(Evas_Object *obj, Edje *ed, Edje_Action_Type action, const char *target)
11849 {
11850    int id = -1;
11851    Edje_Program *tar;
11852    Edje_Real_Part *rp;
11853 
11854    switch (action)
11855      {
11856       case EDJE_ACTION_TYPE_STATE_SET:
11857       case EDJE_ACTION_TYPE_SIGNAL_EMIT:
11858       case EDJE_ACTION_TYPE_DRAG_VAL_SET:
11859       case EDJE_ACTION_TYPE_DRAG_VAL_STEP:
11860       case EDJE_ACTION_TYPE_DRAG_VAL_PAGE:
11861       case EDJE_ACTION_TYPE_FOCUS_SET:
11862       case EDJE_ACTION_TYPE_FOCUS_OBJECT:
11863 #ifdef HAVE_EPHYSICS
11864       case EDJE_ACTION_TYPE_PHYSICS_FORCES_CLEAR:
11865       case EDJE_ACTION_TYPE_PHYSICS_STOP:
11866       case EDJE_ACTION_TYPE_PHYSICS_ROT_SET:
11867 #endif
11868         /* the target is a part */
11869         rp = _edje_real_part_get(ed, target);
11870         if (!rp) return -1;
11871         id = rp->part->id;
11872         break;
11873 
11874       case EDJE_ACTION_TYPE_ACTION_STOP:
11875         /* the target is a program */
11876         tar = _edje_program_get_byname(obj, target);
11877         if (!tar) return -1;
11878         id = tar->id;
11879         break;
11880 
11881       default:
11882         return -1;
11883      }
11884 
11885    return id;
11886 }
11887 
11888 EAPI Eina_Bool
edje_edit_program_target_add(Evas_Object * obj,const char * prog,const char * target)11889 edje_edit_program_target_add(Evas_Object *obj, const char *prog, const char *target)
11890 {
11891    int id;
11892    Edje_Program_Target *t;
11893 
11894    GET_ED_OR_RETURN(EINA_FALSE);
11895    GET_EPR_OR_RETURN(EINA_FALSE);
11896 
11897    id = _program_target_id_get(obj, ed, epr->action, target);
11898    if (id == -1) return EINA_FALSE;
11899 
11900    t = _alloc(sizeof(Edje_Program_Target));
11901    if (!t) return EINA_FALSE;
11902 
11903    t->id = id;
11904    epr->targets = eina_list_append(epr->targets, t);
11905 
11906    return EINA_TRUE;
11907 }
11908 
11909 EAPI Eina_Bool
edje_edit_program_target_insert_at(Evas_Object * obj,const char * prog,const char * target,int place)11910 edje_edit_program_target_insert_at(Evas_Object *obj, const char *prog, const char *target, int place)
11911 {
11912    int id;
11913    Edje_Program_Target *t;
11914    Eina_List *l;
11915 
11916    GET_ED_OR_RETURN(EINA_FALSE);
11917    GET_EPR_OR_RETURN(EINA_FALSE);
11918 
11919    id = _program_target_id_get(obj, ed, epr->action, target);
11920    if (id == -1) return EINA_FALSE;
11921 
11922    t = _alloc(sizeof(Edje_Program_Target));
11923    if (!t) return EINA_FALSE;
11924 
11925    t->id = id;
11926    if ((unsigned)place >= eina_list_count(epr->targets))
11927      epr->targets = eina_list_append(epr->targets, t);
11928    else
11929      {
11930         l = eina_list_nth_list(epr->targets, place);
11931         epr->targets = eina_list_prepend_relative_list(epr->targets, t, l);
11932      }
11933 
11934    return EINA_TRUE;
11935 }
11936 
11937 EAPI Eina_Bool
edje_edit_program_target_del(Evas_Object * obj,const char * prog,const char * target)11938 edje_edit_program_target_del(Evas_Object *obj, const char *prog, const char *target)
11939 {
11940    int id;
11941    Eina_List *l;
11942    Edje_Program_Target *t;
11943 
11944    GET_ED_OR_RETURN(EINA_FALSE);
11945    GET_EPR_OR_RETURN(EINA_FALSE);
11946 
11947    id = _program_target_id_get(obj, ed, epr->action, target);
11948    if (id == -1) return EINA_FALSE;
11949 
11950    EINA_LIST_FOREACH(epr->targets, l, t)
11951      if (t->id == id)
11952        break;
11953    epr->targets = eina_list_remove_list(epr->targets, l);
11954    free(t);
11955 
11956    return EINA_TRUE;
11957 }
11958 
11959 static Eina_List *
_edje_program_afters_get(Evas_Object * obj,Edje_Program * epr)11960 _edje_program_afters_get(Evas_Object *obj, Edje_Program *epr)
11961 {
11962    Eina_List *l, *afters = NULL;
11963    Edje_Program_After *a;
11964 
11965    GET_ED_OR_RETURN(NULL);
11966 
11967    // printf("GET AFTERS for program: %s [count: %d]\n", prog, eina_list_count(epr->after));
11968    EINA_LIST_FOREACH(epr->after, l, a)
11969      {
11970         Edje_Program *p = NULL;
11971 
11972         p = ed->collection->patterns.table_programs[a->id % ed->collection->patterns.table_programs_size];
11973         if (p && p->name)
11974           {
11975              //printf("   a: %d name: %s\n", a->id, p->name);
11976              afters = eina_list_append(afters, eina_stringshare_add(p->name));
11977           }
11978      }
11979    return afters;
11980 }
11981 
11982 EAPI Eina_List *
edje_edit_program_afters_get(Evas_Object * obj,const char * prog)11983 edje_edit_program_afters_get(Evas_Object *obj, const char *prog)
11984 {
11985    GET_EPR_OR_RETURN(NULL);
11986 
11987    return _edje_program_afters_get(obj, epr);
11988 }
11989 
11990 EAPI Eina_Bool
edje_edit_program_afters_clear(Evas_Object * obj,const char * prog)11991 edje_edit_program_afters_clear(Evas_Object *obj, const char *prog)
11992 {
11993    GET_EPR_OR_RETURN(EINA_FALSE);
11994 
11995    while (epr->after)
11996      {
11997         Edje_Program_After *pa;
11998 
11999         pa = eina_list_data_get(epr->after);
12000         epr->after = eina_list_remove_list(epr->after, epr->after);
12001         free(pa);
12002      }
12003 
12004    return EINA_TRUE;
12005 }
12006 
12007 EAPI Eina_Bool
edje_edit_program_after_add(Evas_Object * obj,const char * prog,const char * after)12008 edje_edit_program_after_add(Evas_Object *obj, const char *prog, const char *after)
12009 {
12010    Edje_Program *af;
12011    Edje_Program_After *a;
12012 
12013    GET_EPR_OR_RETURN(EINA_FALSE);
12014 
12015    af = _edje_program_get_byname(obj, after);
12016    if (!af) return EINA_FALSE;
12017 
12018    a = _alloc(sizeof(Edje_Program_After));
12019    if (!a) return EINA_FALSE;
12020 
12021    a->id = af->id;
12022 
12023    epr->after = eina_list_append(epr->after, a);
12024 
12025    return EINA_TRUE;
12026 }
12027 
12028 EAPI Eina_Bool
edje_edit_program_after_insert_at(Evas_Object * obj,const char * prog,const char * after,int place)12029 edje_edit_program_after_insert_at(Evas_Object *obj, const char *prog, const char *after, int place)
12030 {
12031    Edje_Program *af;
12032    Edje_Program_After *a;
12033    Eina_List *l;
12034 
12035    GET_EPR_OR_RETURN(EINA_FALSE);
12036 
12037    if (place < 0)
12038      return EINA_FALSE;
12039 
12040    af = _edje_program_get_byname(obj, after);
12041    if (!af) return EINA_FALSE;
12042 
12043    a = _alloc(sizeof(Edje_Program_After));
12044    if (!a) return EINA_FALSE;
12045 
12046    a->id = af->id;
12047 
12048    if ((unsigned)place >= eina_list_count(epr->after))
12049      epr->after = eina_list_append(epr->after, a);
12050    else
12051      {
12052         l = eina_list_nth_list(epr->after, place);
12053         epr->after = eina_list_prepend_relative_list(epr->after, a, l);
12054      }
12055 
12056    return EINA_TRUE;
12057 }
12058 
12059 EAPI Eina_Bool
edje_edit_program_after_del(Evas_Object * obj,const char * prog,const char * after)12060 edje_edit_program_after_del(Evas_Object *obj, const char *prog, const char *after)
12061 {
12062    Edje_Program *af;
12063    Edje_Program_After *a;
12064    Eina_List *l;
12065 
12066    GET_EPR_OR_RETURN(EINA_FALSE);
12067 
12068    af = _edje_program_get_byname(obj, after);
12069    if (!af) return EINA_FALSE;
12070 
12071    EINA_LIST_FOREACH(epr->after, l, a)
12072      if (a->id == af->id)
12073        {
12074           epr->after = eina_list_remove_list(epr->after, l);
12075           break;
12076        }
12077 
12078    return EINA_TRUE;
12079 }
12080 
12081 EAPI const char *
edje_edit_program_api_name_get(Evas_Object * obj,const char * prog)12082 edje_edit_program_api_name_get(Evas_Object *obj, const char *prog)
12083 {
12084    GET_EPR_OR_RETURN(NULL);
12085 
12086    return eina_stringshare_add(epr->api.name);
12087 }
12088 
12089 EAPI const char *
edje_edit_program_api_description_get(Evas_Object * obj,const char * prog)12090 edje_edit_program_api_description_get(Evas_Object *obj, const char *prog)
12091 {
12092    GET_EPR_OR_RETURN(NULL);
12093 
12094    return eina_stringshare_add(epr->api.description);
12095 }
12096 
12097 EAPI Eina_Bool
edje_edit_program_api_name_set(Evas_Object * obj,const char * prog,const char * name)12098 edje_edit_program_api_name_set(Evas_Object *obj, const char *prog, const char *name)
12099 {
12100    GET_ED_OR_RETURN(EINA_FALSE);
12101    GET_EPR_OR_RETURN(EINA_FALSE);
12102 
12103    _edje_if_string_replace(ed, &epr->api.name, name);
12104 
12105    return EINA_TRUE;
12106 }
12107 
12108 EAPI Eina_Bool
edje_edit_program_api_description_set(Evas_Object * obj,const char * prog,const char * description)12109 edje_edit_program_api_description_set(Evas_Object *obj, const char *prog, const char *description)
12110 {
12111    GET_ED_OR_RETURN(EINA_FALSE);
12112    GET_EPR_OR_RETURN(EINA_FALSE);
12113 
12114    _edje_if_string_replace(ed, &epr->api.description, description);
12115 
12116    return EINA_TRUE;
12117 }
12118 
12119 /*************************/
12120 /*  EMBRYO SCRIPTS  API  */
12121 /*************************/
12122 EAPI char *
edje_edit_script_get(Evas_Object * obj)12123 edje_edit_script_get(Evas_Object *obj)
12124 {
12125    GET_EED_OR_RETURN(NULL);
12126    GET_ED_OR_RETURN(NULL);
12127 
12128    if (!ed->collection) return NULL;
12129    if (!eed->embryo_source) return NULL;
12130 
12131    return strdup(eed->embryo_source);
12132 }
12133 
12134 EAPI Eina_Bool
edje_edit_script_set(Evas_Object * obj,const char * code)12135 edje_edit_script_set(Evas_Object *obj, const char *code)
12136 {
12137    GET_EED_OR_RETURN(EINA_FALSE);
12138 
12139    free(eed->embryo_source);
12140    free(eed->embryo_processed);
12141 
12142    if (code)
12143      eed->embryo_source = strdup(code);
12144    else
12145      eed->embryo_source = NULL;
12146    eed->embryo_processed = NULL;
12147 
12148    eed->embryo_source_dirty = EINA_TRUE;
12149 
12150    _edje_edit_flag_script_dirty(eed, EINA_FALSE);
12151    return EINA_TRUE;
12152 }
12153 
12154 EAPI char *
edje_edit_script_program_get(Evas_Object * obj,const char * prog)12155 edje_edit_script_program_get(Evas_Object *obj, const char *prog)
12156 {
12157    Program_Script *ps;
12158 
12159    GET_EED_OR_RETURN(NULL);
12160    GET_EPR_OR_RETURN(NULL);
12161 
12162    if (epr->action != EDJE_ACTION_TYPE_SCRIPT)
12163      return NULL;
12164 
12165    ps = eina_hash_find(eed->program_scripts, &epr->id);
12166    if (!ps) /* mmm? it should be there, even if empty */
12167      return NULL;
12168 
12169    return ps->code ? strdup(ps->code) : NULL;
12170 }
12171 
12172 EAPI Eina_Bool
edje_edit_script_program_set(Evas_Object * obj,const char * prog,const char * code)12173 edje_edit_script_program_set(Evas_Object *obj, const char *prog, const char *code)
12174 {
12175    Program_Script *ps;
12176 
12177    GET_EED_OR_RETURN(EINA_FALSE);
12178    GET_EPR_OR_RETURN(EINA_FALSE);
12179 
12180    if (epr->action != EDJE_ACTION_TYPE_SCRIPT)
12181      return EINA_FALSE;
12182 
12183    ps = eina_hash_find(eed->program_scripts, &epr->id);
12184    if (!ps) /* ???? how so? */
12185      return EINA_FALSE;
12186 
12187    free(ps->code);
12188    free(ps->processed);
12189 
12190    if (code)
12191      ps->code = strdup(code);
12192    else
12193      ps->code = NULL;
12194    ps->processed = NULL;
12195    ps->dirty = EINA_TRUE;
12196 
12197    _edje_edit_flag_script_dirty(eed, EINA_FALSE);
12198    return EINA_TRUE;
12199 }
12200 
12201 static int
__part_replace(Edje_Edit * eed,char * pcode,char * name)12202 __part_replace(Edje_Edit *eed, char *pcode, char *name)
12203 {
12204    int id;
12205 
12206    id = _edje_part_id_find(eed->base, name);
12207    if (id < 0)
12208      return 0;
12209    return eina_convert_itoa(id, pcode);
12210 }
12211 
12212 static int
__program_replace(Edje_Edit * eed,char * pcode,char * name)12213 __program_replace(Edje_Edit *eed, char *pcode, char *name)
12214 {
12215    int id;
12216 
12217    id = _edje_program_id_find(eed, name);
12218    if (id < 0)
12219      return 0;
12220    return eina_convert_itoa(id, pcode);
12221 }
12222 
12223 static int
__group_replace(Edje_Edit * eed EINA_UNUSED,char * pcode,char * name)12224 __group_replace(Edje_Edit *eed EINA_UNUSED, char *pcode, char *name)
12225 {
12226    strcpy(pcode, name);
12227    return strlen(name) + 1;
12228 }
12229 
12230 static int
__image_replace(Edje_Edit * eed,char * pcode,char * name)12231 __image_replace(Edje_Edit *eed, char *pcode, char *name)
12232 {
12233    int id;
12234 
12235    id = _edje_image_id_find(eed, name);
12236    if (id < 0)
12237      return 0;
12238    return eina_convert_itoa(id, pcode);
12239 }
12240 
12241 static char *
_edje_edit_script_process(Edje_Edit * eed,const char * progname,char * code)12242 _edje_edit_script_process(Edje_Edit *eed, const char *progname, char *code)
12243 {
12244    char *pcode, *psrc, *pdst;
12245    int codesize, pcodesize;
12246    int quoted = 0, escaped = 0;
12247    int line = 1;
12248    Eina_Bool success = EINA_TRUE;
12249 
12250    codesize = strlen(code);
12251    pcode = malloc(codesize + 1);
12252    if (!pcode)
12253      return NULL;
12254 
12255    pcodesize = 0;
12256    psrc = code;
12257    pdst = pcode;
12258    while (*psrc)
12259      {
12260         if (!quoted)
12261           {
12262              char *ptr = NULL;
12263              const char *what = NULL;
12264              int (*func)(Edje_Edit *, char *, char *);
12265 
12266              if (*psrc == 'P')
12267                {
12268                   if (!strncmp(psrc, "PART:\"", 6))
12269                     {
12270                        psrc += 6;
12271                        ptr = psrc;
12272                        func = __part_replace;
12273                        what = "part";
12274                     }
12275                   else if (!strncmp(psrc, "PROGRAM:\"", 9))
12276                     {
12277                        psrc += 9;
12278                        ptr = psrc;
12279                        func = __program_replace;
12280                        what = "program";
12281                     }
12282                }
12283              else if (*psrc == 'G')
12284                {
12285                   if (!strncmp(psrc, "GROUP:\"", 7))
12286                     {
12287                        psrc += 7;
12288                        ptr = psrc;
12289                        func = __group_replace;
12290                        what = "group";
12291                     }
12292                }
12293              else if (*psrc == 'I')
12294                {
12295                   if (!strncmp(psrc, "IMAGE:\"", 7))
12296                     {
12297                        psrc += 7;
12298                        ptr = psrc;
12299                        func = __image_replace;
12300                        what = "image";
12301                     }
12302                }
12303              else if (*psrc == '#')
12304                {
12305                   while (*psrc)
12306                     if (*psrc == '\n')
12307                       break;
12308                   line++;
12309                   continue;
12310                }
12311              else if (*psrc == '\"')
12312                quoted = 1;
12313              else if (*psrc == '\n')
12314                line++;
12315 
12316              if (ptr)
12317                {
12318                   int i = 0, inesc = 0;
12319                   char *name;
12320                   while (*psrc)
12321                     {
12322                        if (!inesc)
12323                          {
12324                             if (*psrc == '\\')
12325                               inesc = 1;
12326                             else if (*psrc == '\"')
12327                               {
12328                                  /* string concatenation as in "foo""bar" */
12329                                  if (*(psrc + 1) != '\"')
12330                                    {
12331                                       psrc++;
12332                                       break;
12333                                    }
12334                                  else
12335                                    psrc++;
12336                               }
12337                          }
12338                        else
12339                          inesc = 0;
12340                        psrc++;
12341                     }
12342                   name = alloca(psrc - ptr);
12343                   inesc = 0;
12344                   while (*ptr)
12345                     {
12346                        if (!inesc)
12347                          {
12348                             if (*ptr == '\\')
12349                               inesc = 1;
12350                             else if (*ptr == '\"')
12351                               {
12352                                  if (*(ptr + 1) == '\"')
12353                                    ptr++;
12354                                  else
12355                                    {
12356                                       name[i] = 0;
12357                                       break;
12358                                    }
12359                               }
12360                             else
12361                               {
12362                                  name[i] = *ptr;
12363                                  name[i + 1] = 0;
12364                                  i++;
12365                               }
12366                          }
12367                        else
12368                          inesc = 0;
12369                        ptr++;
12370                     }
12371                   i = func(eed, pdst, name);
12372                   if (!i)
12373                     {
12374                        Edje_Edit_Script_Error *se;
12375                        se = malloc(sizeof(Edje_Edit_Script_Error));
12376                        se->program_name = progname ?
12377                          eina_stringshare_add(progname) : NULL;
12378                        se->line = line;
12379                        se->error_str = eina_stringshare_printf(
12380                            "Referenced %s '%s' could not be found in object.",
12381                            what, name);
12382                        eed->errors = eina_list_append(eed->errors, se);
12383                        success = EINA_FALSE;
12384                     }
12385                   else
12386                     {
12387                        pcodesize += i;
12388                        pdst += i;
12389                     }
12390                   /* replaced reference for the right value, now go
12391                    * to the next iteration */
12392                   continue;
12393                }
12394           }
12395         else
12396           {
12397              if (!escaped)
12398                {
12399                   if (*psrc == '\"')
12400                     quoted = 0;
12401                   else if (*psrc == '\\')
12402                     escaped = 1;
12403                }
12404              else if (escaped)
12405                escaped = 0;
12406           }
12407         *pdst = *psrc;
12408         pdst++;
12409         psrc++;
12410         pcodesize++;
12411      }
12412 
12413    if (!success)
12414      {
12415         free(pcode);
12416         return NULL;
12417      }
12418 
12419    if (pcodesize < codesize)
12420      pcode = realloc(pcode, pcodesize + 1);
12421    pcode[pcodesize] = 0;
12422 
12423    return pcode;
12424 }
12425 
12426 static Eina_Bool
_edje_edit_embryo_rebuild(Edje_Edit * eed)12427 _edje_edit_embryo_rebuild(Edje_Edit *eed)
12428 {
12429    FILE *f;
12430    int fd, size, ret;
12431    Eina_Tmpstr *tmp_in;
12432    Eina_Tmpstr *tmp_out;
12433    char embryo_cc_path[PATH_MAX] = "";
12434    char inc_path[PATH_MAX] = "";
12435    char buf[PATH_MAX + PATH_MAX + PATH_MAX + 128];
12436    Eina_Iterator *it;
12437    Program_Script *ps;
12438    Edje_Part_Collection *edc;
12439    Eina_Bool success = EINA_TRUE; /* we are optimists! */
12440    Edje_Edit_Script_Error *se;
12441    Eina_Prefix *pfx;
12442 
12443    EINA_LIST_FREE(eed->errors, se)
12444      {
12445         eina_stringshare_del(se->program_name);
12446         eina_stringshare_del(se->error_str);
12447         free(se);
12448      }
12449 
12450    pfx = eina_prefix_new(NULL, /* argv[0] value (optional) */
12451                          edje_init, /* an optional symbol to check path of */
12452                          "EDJE", /* env var prefix to use (XXX_PREFIX, XXX_BIN_DIR etc. */
12453                          "edje", /* dir to add after "share" (PREFIX/share/DIRNAME) */
12454                          "include/edje.inc", /* a magic file to check for in PREFIX/share/DIRNAME for success */
12455                          PACKAGE_BIN_DIR,    /* package bin dir @ compile time */
12456                          PACKAGE_LIB_DIR,    /* package lib dir @ compile time */
12457                          PACKAGE_DATA_DIR,   /* package data dir @ compile time */
12458                          PACKAGE_DATA_DIR    /* if locale needed  use LOCALE_DIR */
12459                          );
12460 #ifdef _WIN32
12461 # define BIN_EXT ".exe"
12462 #else
12463 # define BIN_EXT
12464 #endif
12465 
12466    bs_binary_get(embryo_cc_path, sizeof(embryo_cc_path), "embryo", "embryo_cc");
12467 
12468    bs_data_path_get(inc_path, sizeof(inc_path), "edje", "include");
12469 
12470 
12471    if (embryo_cc_path[0] == '\0')
12472      {
12473         snprintf(embryo_cc_path, sizeof(embryo_cc_path),
12474                  "%s/embryo_cc" BIN_EXT,
12475                  eina_prefix_bin_get(pfx));
12476         snprintf(inc_path, sizeof(inc_path),
12477                  "%s/include",
12478                  eina_prefix_data_get(pfx));
12479      }
12480 #undef BIN_EXT
12481 
12482    eina_prefix_free(pfx);
12483 
12484    fd = eina_file_mkstemp("edje_edit.sma-tmp-XXXXXX", &tmp_in);
12485    if (fd < 0)
12486      return EINA_FALSE;  /* FIXME: report something */
12487 
12488    f = fdopen(fd, "wb");
12489    if (!f)
12490      {
12491         close(fd);
12492         unlink(tmp_in);
12493         return EINA_FALSE;
12494      }
12495 
12496    fprintf(f, "#include <edje>\n");
12497    if (eed->embryo_source)
12498      {
12499         if (eed->all_dirty)
12500           {
12501              free(eed->embryo_processed);
12502              eed->embryo_processed = NULL;
12503           }
12504         if (!eed->embryo_processed)
12505           eed->embryo_processed = _edje_edit_script_process(eed, NULL,
12506                                                             eed->embryo_source);
12507         if (!eed->embryo_processed)
12508           {
12509              /* oops.. an error finding references parts or something.
12510               * we could flag it and do some lighter processing of the
12511               * rest of the scripts, in order to find all the errors of
12512               * this kind and report them at once, but knowing already
12513               * that the script will not compile we can avoid some work
12514               */
12515              success = EINA_FALSE;
12516           }
12517         else
12518           fprintf(f, "%s", eed->embryo_processed);
12519      }
12520 
12521    it = eina_hash_iterator_data_new(eed->program_scripts);
12522    EINA_ITERATOR_FOREACH(it, ps)
12523      {
12524         Edje_Program *epr;
12525 
12526         if (ps->delete_me)
12527           continue;
12528         if (eed->all_dirty)
12529           {
12530              free(ps->processed);
12531              ps->processed = NULL;
12532           }
12533         epr = eed->base->collection->patterns.table_programs[ps->id];
12534         if (!ps->processed)
12535           ps->processed = _edje_edit_script_process(eed, epr->name, ps->code);
12536         if (!ps->processed)
12537           {
12538              /* oops.. an error finding references parts or something.
12539               * we could flag it and do some lighter processing of the
12540               * rest of the scripts, in order to find all the errors of
12541               * this kind and report them at once, but knowing already
12542               * that the script will not compile we can avoid some work
12543               */
12544              success = EINA_FALSE;
12545              continue;
12546           }
12547         fprintf(f, "public _p%i(sig[], src[]) {\n", ps->id);
12548         fprintf(f, "%s", ps->processed);
12549         fprintf(f, "}\n");
12550      }
12551    eina_iterator_free(it);
12552 
12553    fclose(f);
12554 
12555    if (!success)
12556      goto almost_out;
12557 
12558    fd = eina_file_mkstemp("edje_edit.amx-tmp-XXXXXX", &tmp_out);
12559    if (fd < 0)
12560      {
12561         success = EINA_FALSE;
12562         goto almost_out;
12563      }
12564 
12565    snprintf(buf, sizeof(buf), "%s -i %s -o %s %s",
12566             embryo_cc_path, inc_path, tmp_out, tmp_in);
12567    ret = system(buf);
12568 
12569    if ((ret < 0) || (ret > 1))
12570      {
12571         success = EINA_FALSE;
12572         close(fd);
12573         goto the_doorway;
12574      }
12575 
12576    f = fdopen(fd, "rb");
12577    if (!f)
12578      {
12579         success = EINA_FALSE;
12580         close(fd);
12581         goto the_doorway;
12582      }
12583 
12584    fseek(f, 0, SEEK_END);
12585    size = ftell(f);
12586    rewind(f);
12587 
12588    free(eed->bytecode);
12589    if (size > 0)
12590      {
12591         eed->bytecode = malloc(size);
12592         if (!eed->bytecode)
12593           {
12594              success = EINA_FALSE;
12595              goto the_way_out;
12596           }
12597         if (fread(eed->bytecode, size, 1, f) != 1)
12598           {
12599              success = EINA_FALSE;
12600              goto the_way_out;
12601           }
12602      }
12603    else
12604      eed->bytecode = NULL;  /* correctness mostly, I don't see why we
12605                                would get a 0 sized program */
12606 
12607    eed->bytecode_size = size;
12608    eed->bytecode_dirty = EINA_TRUE;
12609    eed->script_need_recompile = EINA_FALSE;
12610    eed->all_dirty = EINA_FALSE;
12611 
12612    edc = eed->base->collection;
12613    embryo_program_free(edc->script);
12614    edc->script = embryo_program_new(eed->bytecode, eed->bytecode_size);
12615    _edje_embryo_script_init(edc);
12616    _edje_var_init(eed->base);
12617 
12618 the_way_out:
12619    fclose(f);
12620 the_doorway:
12621    if (tmp_out)
12622      {
12623         unlink(tmp_out);
12624         eina_tmpstr_del(tmp_out);
12625      }
12626 almost_out:
12627    unlink(tmp_in);
12628    eina_tmpstr_del(tmp_in);
12629 
12630    return success;
12631 }
12632 
12633 EAPI Eina_Bool
edje_edit_script_compile(Evas_Object * obj)12634 edje_edit_script_compile(Evas_Object *obj)
12635 {
12636    GET_EED_OR_RETURN(EINA_FALSE);
12637 
12638    if (!eed->script_need_recompile)
12639      return EINA_TRUE;
12640 
12641    return _edje_edit_embryo_rebuild(eed);
12642 }
12643 
12644 EAPI const Eina_List *
edje_edit_script_error_list_get(Evas_Object * obj)12645 edje_edit_script_error_list_get(Evas_Object *obj)
12646 {
12647    GET_EED_OR_RETURN(NULL);
12648    return eed->errors;
12649 }
12650 
12651 /***************************/
12652 /*  EDC SOURCE GENERATION  */
12653 /***************************/
12654 #define I0 ""
12655 #define I1 "   "
12656 #define I2 "      "
12657 #define I3 "         "
12658 #define I4 "            "
12659 #define I5 "               "
12660 #define I6 "                  "
12661 #define I7 "                     "
12662 
12663 #define BUF_APPEND(STR) \
12664   ret &= eina_strbuf_append(buf, STR)
12665 
12666 #define BUF_APPENDF(FMT, ...) \
12667   ret &= eina_strbuf_append_printf(buf, FMT, ##__VA_ARGS__)
12668 
12669 #define COLLECT_RESOURCE(condition_data, list)           \
12670   if (condition_data)                                    \
12671     {                                                    \
12672        if (!eina_list_data_find(list, condition_data))   \
12673          list = eina_list_append(list, condition_data);  \
12674     }
12675 
12676 static const char *types[] = {"NONE", "RECT", "TEXT", "IMAGE", "SWALLOW", "TEXTBLOCK", "GRADIENT", "GROUP", "BOX", "TABLE", "EXTERNAL", "PROXY", "SPACER"};
12677 static const char *effects[] = {"NONE", "PLAIN", "OUTLINE", "SOFT_OUTLINE", "SHADOW", "SOFT_SHADOW", "OUTLINE_SHADOW", "OUTLINE_SOFT_SHADOW", "FAR_SHADOW", "FAR_SOFT_SHADOW", "GLOW"};
12678 static const char *shadow_direction[] = {"BOTTOM_RIGHT", "BOTTOM", "BOTTOM_LEFT", "LEFT", "TOP_LEFT", "TOP", "TOP_RIGHT", "RIGHT"};
12679 static const char *prefers[] = {"NONE", "VERTICAL", "HORIZONTAL", "BOTH", "SOURCE"};
12680 static const char *entry_mode[] = {"NONE", "PLAIN", "EDITABLE", "PASSWORD"};
12681 static const char *aspect_mode[] = {"NONE", "NEITHER", "HORIZONTAL", "VERTICAL", "BOTH"};
12682 
12683 static Eina_Bool
12684  _edje_generate_source_of_group(Edje *ed, Edje_Part_Collection_Directory_Entry *pce, Eina_Strbuf *buf);
12685 
12686 static Eina_Bool
12687  _edje_generate_source_of_style(Edje *ed, const char *name, Eina_Strbuf *buf);
12688 
12689 static Eina_Bool
12690  _edje_generate_source_of_colorclass(Edje *ed, const char *name, Eina_Strbuf *buf);
12691 
12692 static Eina_Strbuf *
_edje_generate_image_set_source(Evas_Object * obj,const char * entry)12693 _edje_generate_image_set_source(Evas_Object *obj, const char *entry)
12694 {
12695    Eina_Strbuf *buf = eina_strbuf_new();
12696    Eina_Bool ret = EINA_FALSE;
12697    if (!buf) return NULL;
12698 
12699    BUF_APPENDF(I1 "set { name: \"%s\";\n", entry);
12700    Eina_List *images = NULL, *ll = NULL;
12701    const char *image_name = NULL;
12702    unsigned int place = 0;
12703 
12704    images = edje_edit_image_set_images_list_get(obj, entry);
12705    EINA_LIST_FOREACH(images, ll, image_name)
12706      {
12707         BUF_APPEND(I2 "image {\n");
12708         int comp = edje_edit_image_compression_type_get(obj, image_name);
12709         if (comp < 0)
12710           {
12711             eina_strbuf_free(buf);
12712             return NULL;
12713           }
12714         BUF_APPENDF(I3 "image: \"%s\" ", image_name);
12715 
12716         if (comp == EDJE_EDIT_IMAGE_COMP_LOSSY)
12717           BUF_APPENDF("LOSSY %d;\n",
12718                       edje_edit_image_compression_rate_get(obj, image_name));
12719         else if (comp == EDJE_EDIT_IMAGE_COMP_LOSSY_ETC1)
12720           BUF_APPENDF("LOSSY_ETC1 %d;\n",
12721                       edje_edit_image_compression_rate_get(obj, image_name));
12722         else if (comp == EDJE_EDIT_IMAGE_COMP_LOSSY_ETC2)
12723           BUF_APPENDF("LOSSY_ETC2 %d;\n",
12724                       edje_edit_image_compression_rate_get(obj, image_name));
12725         else if (comp == EDJE_EDIT_IMAGE_COMP_RAW)
12726           BUF_APPEND("RAW;\n");
12727         else if (comp == EDJE_EDIT_IMAGE_COMP_USER)
12728           BUF_APPEND("USER;\n");
12729         else
12730           BUF_APPEND("COMP;\n");
12731 
12732         int min_w = 0, min_h = 0, max_w = 0, max_h = 0;
12733         edje_edit_image_set_image_min_get(obj, entry, place, &min_w, &min_h);
12734         edje_edit_image_set_image_max_get(obj, entry, place, &max_w, &max_h);
12735         if (min_w != 0 || min_h != 0 || max_w != 0 || max_h != 0)
12736           BUF_APPENDF(I3 "size: %d %d %d %d;\n", min_w, min_h, max_w, max_h);
12737 
12738         int l = 0, r = 0, t = 0, b = 0;
12739         edje_edit_image_set_image_border_get(obj, entry, place, &l, &r, &t, &b);
12740         if (l != 0 || r != 0 || t != 0 || b != 0)
12741           BUF_APPENDF(I3 "border: %d %d %d %d;\n", l, r, t, b);
12742 
12743         double scale_by = 0;
12744         scale_by = edje_edit_image_set_image_border_scale_get(obj, entry, place);
12745         if (NEQ(scale_by, 0))
12746           BUF_APPENDF(I3 "border_scale_by: %.3f;\n", scale_by);
12747 
12748         BUF_APPEND(I2 "}\n");
12749         place++;
12750      }
12751    BUF_APPEND(I1 "}\n");
12752 
12753    return buf;
12754 }
12755 
12756 
12757 static Eina_Strbuf *
_edje_generate_image_source(Evas_Object * obj,const char * entry)12758 _edje_generate_image_source(Evas_Object *obj, const char *entry)
12759 {
12760    Eina_Strbuf *buf = eina_strbuf_new();
12761    Eina_Bool ret = EINA_TRUE;
12762    if (!buf) return NULL;
12763 
12764    int comp = edje_edit_image_compression_type_get(obj, entry);
12765    if (comp < 0) goto error;
12766 
12767    BUF_APPENDF("image: \"%s\" ", entry);
12768 
12769    if (comp == EDJE_EDIT_IMAGE_COMP_LOSSY)
12770      BUF_APPENDF("LOSSY %d;\n",
12771                  edje_edit_image_compression_rate_get(obj, entry));
12772    else if (comp == EDJE_EDIT_IMAGE_COMP_LOSSY_ETC1)
12773      BUF_APPENDF("LOSSY_ETC1 %d;\n",
12774                  edje_edit_image_compression_rate_get(obj, entry));
12775    else if (comp == EDJE_EDIT_IMAGE_COMP_LOSSY_ETC2)
12776      BUF_APPENDF("LOSSY_ETC2 %d;\n",
12777                  edje_edit_image_compression_rate_get(obj, entry));
12778    else if (comp == EDJE_EDIT_IMAGE_COMP_RAW)
12779      BUF_APPEND("RAW;\n");
12780    else if (comp == EDJE_EDIT_IMAGE_COMP_USER)
12781      BUF_APPEND("USER;\n");
12782    else
12783      BUF_APPEND("COMP;\n");
12784 
12785    if (!ret) goto error;
12786 
12787    return buf;
12788 
12789 error:
12790    ERR("Generating EDC for Image");
12791    eina_strbuf_free(buf);
12792    return NULL;
12793 }
12794 
12795 static const char *
_edje_edit_source_generate(Evas_Object * obj,Eina_Bool without_global_data)12796 _edje_edit_source_generate(Evas_Object *obj, Eina_Bool without_global_data)
12797 {
12798    Edje_Part_Collection_Directory_Entry *ce;
12799    Edje_Part *part;
12800    Edje_Part_Description_Common *part_desc;
12801    Edje_Part_Description_Image *part_desc_image;
12802    Edje_Part_Description_Text *part_desc_text;
12803    unsigned short i;
12804    unsigned int j;
12805    const char *entry;
12806    const char *str;
12807    Eina_Strbuf *buf = NULL;
12808    Eina_Bool ret = EINA_TRUE;
12809    Eina_List *images = NULL, *color_classes = NULL, *styles = NULL, *fonts = NULL;
12810    Eina_List *images_set = NULL;
12811    Eina_List *sounds = NULL;
12812    Eina_List *l;
12813 
12814    GET_ED_OR_RETURN(NULL);
12815    GET_EED_OR_RETURN(NULL);
12816 
12817    if (!ed->file) return NULL;
12818 
12819    ce = eina_hash_find(ed->file->collection, ed->group);
12820    if (!ce) return NULL;
12821 
12822    /* Go through all of group's parts to find all resources needed for that group. */
12823    for (i = 0; i < ed->table_parts_size; i++)
12824      {
12825         part = ed->table_parts[i]->part;
12826         part_desc = (Edje_Part_Description_Common *)part->default_desc;
12827 
12828         /* find all image parts and collect all images required by those parts. */
12829         if (part->type == EDJE_PART_TYPE_IMAGE)
12830           {
12831              /*  parse "default" description of this part. */
12832              part_desc_image = (Edje_Part_Description_Image *)part->default_desc;
12833 
12834              if (part_desc_image->image.set)
12835                {
12836                   entry = _edje_set_name_find(eed, part_desc_image->image.id);
12837                   COLLECT_RESOURCE(entry, images_set);
12838                }
12839              else
12840                {
12841                   /* find image name according to it's id that is in description */
12842                   entry = _edje_image_name_find(eed, part_desc_image->image.id);
12843                   COLLECT_RESOURCE(entry, images);
12844                }
12845              for (j = 0; j < part_desc_image->image.tweens_count; j++)
12846                {
12847                   entry = _edje_image_name_find(eed, part_desc_image->image.tweens[j]->id);
12848                   COLLECT_RESOURCE(entry, images);
12849                }
12850              /*  look through all other's descriptions. */
12851              for (j = 0; j < part->other.desc_count; j++)
12852                {
12853                   part_desc_image = (Edje_Part_Description_Image *)part->other.desc[j];
12854 
12855                   if (part_desc_image->image.set)
12856                     {
12857                        entry = _edje_set_name_find(eed, part_desc_image->image.id);
12858                        COLLECT_RESOURCE(entry, images_set);
12859                     }
12860                   else
12861                     {
12862                        /* find image name according to it's id that is in description */
12863                        entry = _edje_image_name_find(eed, part_desc_image->image.id);
12864                        COLLECT_RESOURCE(entry, images);
12865                     }
12866               }
12867           }
12868         /* find all text, textblock part and fonts, styles required by those parts. */
12869         if ((part->type == EDJE_PART_TYPE_TEXTBLOCK) ||
12870             (part->type == EDJE_PART_TYPE_TEXT))
12871           {
12872              part_desc_text = (Edje_Part_Description_Text *)part->default_desc;
12873              COLLECT_RESOURCE(part_desc_text->text.style.str, styles);
12874              if (part_desc_text->text.font.str)
12875                {
12876                   Edje_Font_Directory_Entry *fnt;
12877                   fnt = eina_hash_find(ed->file->fonts, part_desc_text->text.font.str);
12878                   COLLECT_RESOURCE(fnt, fonts);
12879                }
12880              for (j = 0; j < part->other.desc_count; j++)
12881                {
12882                   part_desc_text = (Edje_Part_Description_Text *)part->other.desc[j];
12883                   COLLECT_RESOURCE(part_desc_text->text.style.str, styles);
12884                   if (part_desc_text->text.font.str)
12885                     {
12886                        Edje_Font_Directory_Entry *fnt;
12887                        fnt = eina_hash_find(ed->file->fonts, part_desc_text->text.font.str);
12888                        COLLECT_RESOURCE(fnt, fonts);
12889                     }
12890                }
12891           }
12892         /* find all color_classes required by those every part. */
12893         COLLECT_RESOURCE(part_desc->color_class, color_classes);
12894         for (j = 0; j < part->other.desc_count; j++)
12895           {
12896              part_desc = part->other.desc[j];
12897              COLLECT_RESOURCE(part_desc->color_class, color_classes);
12898           }
12899      }
12900    /* collect all sound samples, that uses in current collection */
12901    for (j = 0;
12902         j < (unsigned int)ed->collection->patterns.table_programs_size;
12903         j++)
12904      {
12905         Edje_Program *epr;
12906         Edje_Sound_Sample *sample;
12907         epr = ed->collection->patterns.table_programs[j];
12908         if ((!epr) || (epr->action != EDJE_ACTION_TYPE_SOUND_SAMPLE))
12909           continue;
12910         for (i = 0; i < (unsigned int)ed->file->sound_dir->samples_count; i++)
12911           {
12912              sample = &ed->file->sound_dir->samples[i];
12913              if (!strcmp(sample->name, epr->sample_name))
12914                {
12915                   COLLECT_RESOURCE(sample, sounds);
12916                   break;
12917                }
12918           }
12919      }
12920 
12921    buf = eina_strbuf_new();
12922 
12923    /* If data items exist, print them */
12924    if (!without_global_data && ed->file->data)
12925      {
12926         Edje_String *es;
12927         size_t data_len = 0;
12928         char *escaped_entry = NULL;
12929         char *escaped_string = NULL;
12930         BUF_APPEND(I0 "data {\n");
12931         Eina_Iterator *it = eina_hash_iterator_key_new(ed->file->data);
12932         EINA_ITERATOR_FOREACH(it, entry)
12933           {
12934              es = eina_hash_find(ed->file->data, entry);
12935              str = edje_string_get(es);
12936              if (!str) break;
12937              data_len = strlen(str);
12938              /* In case when data ends with '\n' character, this item recognize
12939               * as data.file. This data will not generated into the source code
12940               * of group. */
12941              if (str[data_len - 1] == '\n') continue;
12942              escaped_entry = eina_str_escape(entry);
12943              escaped_string = eina_str_escape(str);
12944              BUF_APPENDF(I1 "item: \"%s\" \"%s\";\n", escaped_entry, escaped_string);
12945              free(escaped_entry);
12946              free(escaped_string);
12947           }
12948         eina_iterator_free(it);
12949         BUF_APPEND(I0 "}\n\n");
12950      }
12951 
12952    if (ed->file->text_classes)
12953      {
12954         BUF_APPEND(I0 "text_classes {\n");
12955         Edje_Text_Class *tc;
12956 
12957         EINA_LIST_FOREACH(ed->file->text_classes, l, tc)
12958           {
12959              BUF_APPENDF(I1 "text_class {\n");
12960              BUF_APPENDF(I2 "name: \"%s\";\n", tc->name);
12961              if (tc->font)
12962                BUF_APPENDF(I2 "font: \"%s\";\n", tc->font);
12963              if (tc->size > 0)
12964                BUF_APPENDF(I2 "size: %d;\n", tc->size);
12965              BUF_APPENDF(I1 "}\n");
12966           }
12967 
12968         BUF_APPEND(I0 "}\n\n");
12969      }
12970 
12971    if (ed->file->size_classes)
12972      {
12973         BUF_APPEND(I0 "size_classes {\n");
12974         Edje_Size_Class *sc;
12975 
12976         EINA_LIST_FOREACH(ed->file->size_classes, l, sc)
12977           {
12978              BUF_APPENDF(I1 "size_class {\n");
12979              BUF_APPENDF(I2 "name: \"%s\";\n", sc->name);
12980              if ((sc->minw > 0) || (sc->minh > 0))
12981                BUF_APPENDF(I2 "min: %d %d;\n", sc->minw, sc->minh);
12982              if ((sc->maxw >= -1) || (sc->maxh >= -1))
12983                BUF_APPENDF(I2 "max: %d %d;\n", sc->maxw, sc->maxh);
12984              BUF_APPENDF(I1 "}\n");
12985           }
12986 
12987         BUF_APPEND(I0 "}\n\n");
12988      }
12989 
12990    /* if images were found, print them */
12991    if (images || images_set)
12992      {
12993         BUF_APPEND(I0 "images {\n");
12994 
12995         EINA_LIST_FOREACH(images, l, entry)
12996           {
12997              Eina_Strbuf *gen_buf = _edje_generate_image_source(obj, entry);
12998              if (!gen_buf) continue;
12999 
13000              BUF_APPENDF(I1 "%s", eina_strbuf_string_get(gen_buf));
13001              eina_strbuf_free(gen_buf);
13002           }
13003 
13004         EINA_LIST_FOREACH(images_set, l, entry)
13005           {
13006              Eina_Strbuf *gen_buf = _edje_generate_image_set_source(obj, entry);
13007              if (!gen_buf) continue;
13008 
13009              BUF_APPENDF("%s", eina_strbuf_string_get(gen_buf));
13010              eina_strbuf_free(gen_buf);
13011           }
13012 
13013 
13014         BUF_APPEND(I0 "}\n\n");
13015         eina_list_free(images);
13016      }
13017    /* if styles were found, print them */
13018    if (styles)
13019      {
13020         BUF_APPEND(I0 "styles {\n");
13021         EINA_LIST_FOREACH(styles, l, entry)
13022           _edje_generate_source_of_style(ed, entry, buf);
13023         BUF_APPEND(I0 "}\n\n");
13024         eina_list_free(styles);
13025      }
13026    /* if fonts were found, print them */
13027    if (fonts)
13028      {
13029         BUF_APPEND(I0 "fonts {\n");
13030         Edje_Font_Directory_Entry *fnt;
13031 
13032         EINA_LIST_FOREACH(fonts, l, fnt)
13033           {
13034              BUF_APPENDF(I1 "font: \"%s\" \"%s\";\n", fnt->file,
13035                          fnt->entry);
13036           }
13037 
13038         BUF_APPEND(I0 "}\n\n");
13039         eina_list_free(fonts);
13040      }
13041    /* if color_classes were found, print them */
13042    if (!without_global_data && color_classes)
13043      {
13044         BUF_APPEND(I0 "color_classes {\n");
13045 
13046         EINA_LIST_FOREACH(color_classes, l, entry)
13047           _edje_generate_source_of_colorclass(ed, entry, buf);
13048 
13049         BUF_APPEND(I0 "}\n\n");
13050         eina_list_free(color_classes);
13051      }
13052 
13053 
13054    /* print the main code of group collections */
13055    if (!without_global_data) BUF_APPEND(I0 "collections {\n");
13056    /* if sounds were found, print them */
13057    if (sounds)
13058      {
13059         Edje_Sound_Sample *uses_sample;
13060         BUF_APPEND(I1 "sounds {\n");
13061         EINA_LIST_FOREACH(sounds, l, uses_sample)
13062           {
13063              BUF_APPEND(I2 "sample {\n");
13064              BUF_APPENDF(I3 "name: \"%s\" ", uses_sample->name);
13065              switch (uses_sample->compression)
13066                {
13067                 case EDJE_SOUND_SOURCE_TYPE_INLINE_RAW:
13068                 {
13069                    BUF_APPEND("RAW;\n");
13070                    break;
13071                 }
13072 
13073                 case EDJE_SOUND_SOURCE_TYPE_INLINE_COMP:
13074                 {
13075                    BUF_APPEND("COMP;\n");
13076                    break;
13077                 }
13078 
13079                 case EDJE_SOUND_SOURCE_TYPE_INLINE_LOSSY:
13080                 {
13081                    BUF_APPENDF("LOSSY %f;\n", uses_sample->quality);
13082                    break;
13083                 }
13084 
13085                 case EDJE_SOUND_SOURCE_TYPE_INLINE_AS_IS:
13086                 {
13087                    BUF_APPEND("AS_IS;\n");
13088                    break;
13089                 }
13090 
13091                 default:
13092                   break;
13093                }
13094              BUF_APPENDF(I3 "source: \"%s\";\n", uses_sample->snd_src);
13095              BUF_APPEND(I2 "}\n");
13096           }
13097         BUF_APPEND(I1 "}\n");
13098      }
13099    _edje_generate_source_of_group(ed, ce, buf);
13100    if (!without_global_data) BUF_APPEND(I0 "}");
13101 
13102    if (!ret)
13103      {
13104         ERR("Generating EDC for This Group.");
13105         eina_strbuf_free(buf);
13106         return NULL;
13107      }
13108 
13109    /* return resulted source code of the group */
13110    str = eina_stringshare_add(eina_strbuf_string_get(buf));
13111    eina_strbuf_free(buf);
13112    return str;
13113 }
13114 
13115 EAPI const char *
edje_edit_source_generate(Evas_Object * obj)13116 edje_edit_source_generate(Evas_Object *obj)
13117 {
13118    return _edje_edit_source_generate(obj, EINA_FALSE);
13119 }
13120 
13121 EAPI const char *
edje_edit_object_source_generate(Evas_Object * obj)13122 edje_edit_object_source_generate(Evas_Object *obj)
13123 {
13124    return _edje_edit_source_generate(obj, EINA_TRUE);
13125 }
13126 
13127 EAPI const char *
edje_edit_data_source_generate(Evas_Object * obj)13128 edje_edit_data_source_generate(Evas_Object *obj)
13129 {
13130    Eina_Strbuf *buf = NULL;
13131    Eina_Bool ret = EINA_TRUE;
13132    Eina_Stringshare *str = NULL;
13133    const char *entry;
13134 
13135    GET_ED_OR_RETURN(NULL);
13136 
13137    if (!ed->file) return NULL;
13138 
13139    buf = eina_strbuf_new();
13140 
13141    /* If data items exist, print them */
13142    if (ed->file->data)
13143      {
13144         Edje_String *es;
13145         size_t data_len = 0;
13146         char *escaped_entry = NULL;
13147         char *escaped_string = NULL;
13148         BUF_APPEND(I0 "data {\n");
13149         Eina_Iterator *it = eina_hash_iterator_key_new(ed->file->data);
13150         EINA_ITERATOR_FOREACH(it, entry)
13151           {
13152              es = eina_hash_find(ed->file->data, entry);
13153              str = edje_string_get(es);
13154              if (!str) break;
13155              data_len = strlen(str);
13156              /* In case when data ends with '\n' character, this item recognize
13157               * as data.file. This data will not generated into the source code
13158               * of group. */
13159              if (str[data_len - 1] == '\n') continue;
13160              escaped_entry = eina_str_escape(entry);
13161              escaped_string = eina_str_escape(str);
13162              BUF_APPENDF(I1 "item: \"%s\" \"%s\";\n", escaped_entry, escaped_string);
13163              free(escaped_entry);
13164              free(escaped_string);
13165           }
13166         eina_iterator_free(it);
13167         BUF_APPEND(I0 "}\n\n");
13168      }
13169 
13170    /* return resulted source code of the group */
13171    if (ret)
13172      str = eina_stringshare_add(eina_strbuf_string_get(buf));
13173    eina_strbuf_free(buf);
13174    return str;
13175 }
13176 
13177 EAPI Eina_List *
edje_edit_object_color_class_list_get(Evas_Object * obj)13178 edje_edit_object_color_class_list_get(Evas_Object *obj)
13179 {
13180    Edje_Part_Collection_Directory_Entry *ce;
13181    Edje_Part *part;
13182    Edje_Part_Description_Common *part_desc;
13183    unsigned int j, i;
13184    Eina_List *color_classes = NULL;
13185 
13186    GET_ED_OR_RETURN(NULL);
13187 
13188    if (!ed->file) return NULL;
13189 
13190    ce = eina_hash_find(ed->file->collection, ed->group);
13191    if (!ce) return NULL;
13192 
13193    /* Go through all of group's parts to find all resources needed for that group. */
13194    for (i = 0; i < ed->table_parts_size; i++)
13195      {
13196         part = ed->table_parts[i]->part;
13197         part_desc = (Edje_Part_Description_Common *)part->default_desc;
13198 
13199         /* find all color_classes required by those every part. */
13200         COLLECT_RESOURCE(part_desc->color_class, color_classes);
13201         for (j = 0; j < part->other.desc_count; j++)
13202           {
13203              part_desc = part->other.desc[j];
13204              COLLECT_RESOURCE(part_desc->color_class, color_classes);
13205           }
13206      }
13207 
13208    return color_classes;
13209 }
13210 
13211 EAPI const char *
edje_edit_color_classes_source_generate(Evas_Object * obj,Eina_List * color_classes)13212 edje_edit_color_classes_source_generate(Evas_Object *obj, Eina_List *color_classes)
13213 {
13214    Eina_Strbuf *buf;
13215    Eina_List *l;
13216    const char *entry;
13217    Eina_Bool ret = EINA_TRUE;
13218    Eina_Stringshare *str = NULL;
13219 
13220    GET_ED_OR_RETURN(NULL);
13221 
13222    buf = eina_strbuf_new();
13223 
13224    BUF_APPEND(I0 "color_classes {\n");
13225 
13226    EINA_LIST_FOREACH(color_classes, l, entry)
13227      _edje_generate_source_of_colorclass(ed, entry, buf);
13228 
13229    BUF_APPEND(I0 "}\n\n");
13230 
13231    if (ret)
13232      str = eina_stringshare_add(eina_strbuf_string_get(buf));
13233    eina_strbuf_free(buf);
13234    return str;
13235 }
13236 
13237 #undef COLLECT_RESOURCE
13238 
13239 static Eina_Bool
_edje_generate_source_of_sizeclass(Edje * ed,const char * name,Eina_Strbuf * buf)13240 _edje_generate_source_of_sizeclass(Edje *ed, const char *name, Eina_Strbuf *buf)
13241 {
13242    Eina_List *l;
13243    Edje_Size_Class *sc;
13244    Eina_Bool ret = EINA_TRUE;
13245 
13246    EINA_LIST_FOREACH(ed->file->size_classes, l, sc)
13247       if (!strcmp(sc->name, name))
13248         {
13249            BUF_APPENDF(I1 "size_class {\n");
13250            BUF_APPENDF(I2 "name: \"%s\";\n", sc->name);
13251            if ((sc->minw > 0) || (sc->minh > 0))
13252              BUF_APPENDF(I2 "min: %d %d;\n", sc->minw, sc->minh);
13253            if ((sc->maxw >= -1) || (sc->maxh >= -1))
13254              BUF_APPENDF(I2 "max: %d %d;\n", sc->maxw, sc->maxh);
13255            BUF_APPENDF(I1 "}\n");
13256         }
13257 
13258    return ret;
13259 }
13260 
13261 static Eina_Bool
_edje_generate_source_of_textclass(Edje * ed,const char * name,Eina_Strbuf * buf)13262 _edje_generate_source_of_textclass(Edje *ed, const char *name, Eina_Strbuf *buf)
13263 {
13264    Eina_List *l;
13265    Edje_Text_Class *tc;
13266    Eina_Bool ret = EINA_TRUE;
13267 
13268    EINA_LIST_FOREACH(ed->file->text_classes, l, tc)
13269       if (!strcmp(tc->name, name))
13270         {
13271            BUF_APPENDF(I1 "text_class {\n");
13272            BUF_APPENDF(I2 "name: \"%s\";\n", tc->name);
13273            if (tc->font)
13274              BUF_APPENDF(I2 "font: \"%s\";\n", tc->font);
13275            if (tc->size > 0)
13276              BUF_APPENDF(I2 "size: %d;\n", tc->size);
13277            BUF_APPENDF(I1 "}\n");
13278         }
13279 
13280    return ret;
13281 }
13282 
13283 static Eina_Bool
_edje_generate_source_of_colorclass(Edje * ed,const char * name,Eina_Strbuf * buf)13284 _edje_generate_source_of_colorclass(Edje *ed, const char *name, Eina_Strbuf *buf)
13285 {
13286    Eina_List *l;
13287    Edje_Color_Class *cc;
13288    Eina_Bool ret = EINA_TRUE;
13289 
13290    EINA_LIST_FOREACH(ed->file->color_classes, l, cc)
13291      if (!strcmp(cc->name, name))
13292        {
13293           BUF_APPENDF(I1 "color_class { name: \"%s\";\n", cc->name);
13294           BUF_APPENDF(I2 "color: %d %d %d %d;\n", cc->r, cc->g, cc->b, cc->a);
13295           BUF_APPENDF(I2 "color2: %d %d %d %d;\n", cc->r2, cc->g2, cc->b2, cc->a2);
13296           BUF_APPENDF(I2 "color3: %d %d %d %d;\n", cc->r3, cc->g3, cc->b3, cc->a3);
13297           BUF_APPEND(I1 "}\n");
13298        }
13299    return ret;
13300 }
13301 
13302 static Eina_Bool
_edje_generate_source_of_style(Edje * ed,const char * name,Eina_Strbuf * buf)13303 _edje_generate_source_of_style(Edje *ed, const char *name, Eina_Strbuf *buf)
13304 {
13305    Eina_List *l, *ll;
13306    Edje_Style *s;
13307    Edje_Style_Tag *t;
13308    Eina_Bool ret = EINA_TRUE;
13309 
13310    int len, i;
13311    #define ESCAPE_VAL(VAL)                     \
13312   for (i = 0, len = strlen(VAL); i < len; i++) \
13313     switch (VAL[i])                            \
13314       {                                        \
13315        case '\n':                              \
13316        {                                       \
13317           BUF_APPENDF("%s", "\\n");            \
13318           break;                               \
13319        }                                       \
13320        case '\t':                              \
13321        {                                       \
13322           BUF_APPENDF("%s", "\\t");            \
13323           break;                               \
13324        }                                       \
13325        case '"':                               \
13326        {                                       \
13327           BUF_APPENDF("%s", "\\\"");           \
13328           break;                               \
13329        }                                       \
13330        case '\\':                              \
13331        {                                       \
13332           BUF_APPENDF("%s", "\\\\");           \
13333           break;                               \
13334        }                                       \
13335        default: BUF_APPENDF("%c", VAL[i]);     \
13336       }
13337 
13338    EINA_LIST_FOREACH(ed->file->styles, l, s)
13339      if (!strcmp(s->name, name))
13340        {
13341           t = s->tags ? s->tags->data : NULL;
13342           BUF_APPENDF(I1 "style { name:\"%s\";\n", s->name);
13343           if (t && t->value)
13344             {
13345                BUF_APPEND(I2 "base: \"");
13346                ESCAPE_VAL(t->value);
13347                BUF_APPEND("\";\n");
13348             }
13349 
13350           EINA_LIST_FOREACH(s->tags, ll, t)
13351             if (ll->prev && t && t->value)
13352               {
13353                  BUF_APPENDF(I2 "tag: \"%s\" \"", t->key);
13354                  ESCAPE_VAL(t->value);
13355                  BUF_APPEND("\";\n");
13356               }
13357           BUF_APPEND(I1 "}\n");
13358           return ret;
13359        }
13360    #undef ESCAPE_VAL
13361    return EINA_FALSE;
13362 }
13363 
13364 static Eina_Bool
_edje_generate_source_of_program(Evas_Object * obj,const char * prog,Eina_Strbuf * buf)13365 _edje_generate_source_of_program(Evas_Object *obj, const char *prog, Eina_Strbuf *buf)
13366 {
13367    Eina_List *l, *ll;
13368    const char *s;
13369    double db, db2, v1, v2, v3, v4;
13370    char *data;
13371    Eina_Bool ret = EINA_TRUE;
13372    Eina_Bool no_transition = EINA_FALSE;
13373    const char *api_name, *api_description;
13374    int tweenmode = 0;
13375 
13376    GET_ED_OR_RETURN(EINA_FALSE);
13377    GET_EED_OR_RETURN(EINA_FALSE);
13378    GET_EPR_OR_RETURN(EINA_FALSE);
13379 
13380    BUF_APPENDF(I3 "program { name: \"%s\";\n", prog);
13381 
13382    /* Signal */
13383    s = eina_stringshare_add(epr->signal);
13384    if ((s != NULL) && (strcmp(s, "")))
13385      {
13386         BUF_APPENDF(I4 "signal: \"%s\";\n", s);
13387         edje_edit_string_free(s);
13388      }
13389 
13390    /* Source */
13391    s = eina_stringshare_add(epr->source);
13392    if ((s != NULL) && (strcmp(s, "")))
13393      {
13394         BUF_APPENDF(I4 "source: \"%s\";\n", s);
13395         edje_edit_string_free(s);
13396      }
13397 
13398    /* Filter */
13399    if (epr->filter.part && epr->filter.state)
13400      {
13401         BUF_APPENDF(I4 "filter: \"%s\" \"%s\";\n",
13402                     epr->filter.part, epr->filter.state);
13403      }
13404 
13405    /* Action */
13406    switch (epr->action)
13407      {
13408       case EDJE_ACTION_TYPE_ACTION_STOP:
13409         BUF_APPEND(I4 "action: ACTION_STOP;\n");
13410         break;
13411 
13412       case EDJE_ACTION_TYPE_STATE_SET:
13413         if (epr->state)
13414           {
13415              BUF_APPENDF(I4 "action: STATE_SET \"%s\" %.2f;\n", epr->state,
13416                          edje_edit_program_value_get(obj, prog));
13417           }
13418         break;
13419 
13420       case EDJE_ACTION_TYPE_SIGNAL_EMIT:
13421         if (epr->state && epr->state2)
13422           BUF_APPENDF(I4 "action: SIGNAL_EMIT \"%s\" \"%s\";\n", epr->state, epr->state2);
13423         break;
13424 
13425       case EDJE_ACTION_TYPE_SCRIPT:
13426       {
13427          Program_Script *ps;
13428 
13429          ps = eina_hash_find(eed->program_scripts, &epr->id);
13430          if (ps && !ps->delete_me)
13431            {
13432               BUF_APPEND(I4 "script {\n");
13433               BUF_APPEND(ps->code);
13434               BUF_APPEND(I4 "}\n");
13435            }
13436       }
13437       break;
13438 
13439       case EDJE_ACTION_TYPE_SOUND_SAMPLE:
13440       {
13441          BUF_APPEND(I4 "action: PLAY_SAMPLE ");
13442          BUF_APPENDF("\"%s\" %.4f", epr->sample_name, epr->speed);
13443          switch (epr->channel)
13444            {
13445             case EDJE_CHANNEL_BACKGROUND:
13446             {
13447                BUF_APPEND(" BACKGROUND");
13448                break;
13449             }
13450 
13451             case EDJE_CHANNEL_MUSIC:
13452             {
13453                BUF_APPEND(" MUSIC");
13454                break;
13455             }
13456 
13457             case EDJE_CHANNEL_FOREGROUND:
13458             {
13459                BUF_APPEND(" FOREGROUND");
13460                break;
13461             }
13462 
13463             case EDJE_CHANNEL_INTERFACE:
13464             {
13465                BUF_APPEND(" INTERFACE");
13466                break;
13467             }
13468 
13469             case EDJE_CHANNEL_INPUT:
13470             {
13471                BUF_APPEND(" INPUT");
13472                break;
13473             }
13474 
13475             case EDJE_CHANNEL_ALERT:
13476             {
13477                BUF_APPEND(" ALERT");
13478                break;
13479             }
13480 
13481             default:
13482               break;
13483            }
13484          BUF_APPENDF(";\n");
13485          break;
13486       }
13487 
13488       case EDJE_ACTION_TYPE_SOUND_TONE:
13489       {
13490          BUF_APPEND(I4 "action: PLAY_TONE ");
13491          BUF_APPENDF("\"%s\" %.4f;\n", epr->tone_name, epr->duration);
13492          break;
13493       }
13494 
13495       case EDJE_ACTION_TYPE_DRAG_VAL_SET:
13496       {
13497          BUF_APPEND(I4 "action: DRAG_VAL_SET ");
13498          BUF_APPENDF("%.4f %.4f;\n", epr->value, epr->value2);
13499          break;
13500       }
13501 
13502       case EDJE_ACTION_TYPE_DRAG_VAL_STEP:
13503       {
13504          BUF_APPEND(I4 "action: DRAG_VAL_STEP ");
13505          BUF_APPENDF("%.4f %.4f;\n", epr->value, epr->value2);
13506          break;
13507       }
13508 
13509       case EDJE_ACTION_TYPE_DRAG_VAL_PAGE:
13510       {
13511          BUF_APPEND(I4 "action: DRAG_VAL_PAGE ");
13512          BUF_APPENDF("%.4f %.4f;\n", epr->value, epr->value2);
13513          break;
13514       }
13515 
13516       case EDJE_ACTION_TYPE_FOCUS_SET:
13517       {
13518          if (epr->seat)
13519            {
13520               BUF_APPEND(I4 "action: FOCUS_SET ");
13521               BUF_APPENDF("\"%s\";\n", epr->seat);
13522            }
13523          else
13524            BUF_APPEND(I4 "action: FOCUS_SET;\n");
13525          break;
13526       }
13527 
13528       case EDJE_ACTION_TYPE_FOCUS_OBJECT:
13529       {
13530          if (epr->seat)
13531            {
13532               BUF_APPEND(I4 "action: FOCUS_OBJECT ");
13533               BUF_APPENDF("\"%s\";\n", epr->seat);
13534            }
13535          else
13536            BUF_APPEND(I4 "action: FOCUS_OBJECT;\n");
13537          break;
13538       }
13539 
13540       case EDJE_ACTION_TYPE_PARAM_COPY:
13541       {
13542          Edje_Real_Part *src_part, *dst_part;
13543 
13544          src_part = ed->table_parts[epr->param.src % ed->table_parts_size];
13545          dst_part = ed->table_parts[epr->param.dst % ed->table_parts_size];
13546 
13547          if (!src_part || !dst_part) break;
13548 
13549          BUF_APPEND(I4 "action: PARAM_COPY ");
13550          BUF_APPENDF("\"%s\" \"%s\" \"%s\" \"%s\";\n",
13551                      src_part->part->name, epr->state,
13552                      dst_part->part->name, epr->state2);
13553          break;
13554       }
13555 
13556       case EDJE_ACTION_TYPE_PARAM_SET:
13557       {
13558          Edje_Real_Part *part;
13559 
13560          part = ed->table_parts[epr->param.dst % ed->table_parts_size];
13561 
13562          if (!part) break;
13563 
13564          BUF_APPEND(I4 "action: PARAM_SET ");
13565          BUF_APPENDF("\"%s\" \"%s\" \"%s\";\n",
13566                      part->part->name, epr->state, epr->state2);
13567          break;
13568        }
13569 
13570       default:
13571         break;
13572      }
13573 
13574    /* Transition */
13575    db = TO_DOUBLE(epr->tween.time);
13576    tweenmode = (epr->tween.mode & (~(EDJE_TWEEN_MODE_OPT_FROM_CURRENT)));
13577    switch (tweenmode)
13578      {
13579       case EDJE_TWEEN_MODE_LINEAR:
13580         if (NEQ(db, ZERO))
13581           BUF_APPENDF(I4 "transition: LINEAR %.5f", db);
13582         else
13583           no_transition = EINA_TRUE;
13584         break;
13585 
13586       case EDJE_TWEEN_MODE_ACCELERATE:
13587         BUF_APPENDF(I4 "transition: ACCELERATE %.5f", db);
13588         break;
13589 
13590       case EDJE_TWEEN_MODE_DECELERATE:
13591         BUF_APPENDF(I4 "transition: DECELERATE %.5f", db);
13592         break;
13593 
13594       case EDJE_TWEEN_MODE_SINUSOIDAL:
13595         BUF_APPENDF(I4 "transition: SINUSOIDAL %.5f", db);
13596         break;
13597 
13598       case EDJE_TWEEN_MODE_ACCELERATE_FACTOR:
13599         v1 = TO_DOUBLE(epr->tween.v1);
13600         BUF_APPENDF(I4 "transition: ACCELERATE_FACTOR %.5f %.5f", db, v1);
13601         break;
13602 
13603       case EDJE_TWEEN_MODE_DECELERATE_FACTOR:
13604         v1 = TO_DOUBLE(epr->tween.v1);
13605         BUF_APPENDF(I4 "transition: DECELERATE_FACTOR %.5f %.5f", db, v1);
13606         break;
13607 
13608       case EDJE_TWEEN_MODE_SINUSOIDAL_FACTOR:
13609         v1 = TO_DOUBLE(epr->tween.v1);
13610         BUF_APPENDF(I4 "transition: SINUSOIDAL_FACTOR %.5f %.5f", db, v1);
13611         break;
13612 
13613       case EDJE_TWEEN_MODE_DIVISOR_INTERP:
13614         v1 = TO_DOUBLE(epr->tween.v1);
13615         v2 = TO_DOUBLE(epr->tween.v2);
13616         BUF_APPENDF(I4 "transition: DIVISOR_INTERP %.5f %.5f %.5f", db, v1, v2);
13617         break;
13618 
13619       case EDJE_TWEEN_MODE_BOUNCE:
13620         v1 = TO_DOUBLE(epr->tween.v1);
13621         v2 = TO_DOUBLE(epr->tween.v2);
13622         BUF_APPENDF(I4 "transition: BOUNCE %.5f %.5f %.5f", db, v1, v2);
13623         break;
13624 
13625       case EDJE_TWEEN_MODE_SPRING:
13626         v1 = TO_DOUBLE(epr->tween.v1);
13627         v2 = TO_DOUBLE(epr->tween.v2);
13628         BUF_APPENDF(I4 "transition: SPRING %.5f %.5f %.5f", db, v1, v2);
13629         break;
13630 
13631       case EDJE_TWEEN_MODE_CUBIC_BEZIER:
13632         v1 = TO_DOUBLE(epr->tween.v1);
13633         v2 = TO_DOUBLE(epr->tween.v2);
13634         v3 = TO_DOUBLE(epr->tween.v3);
13635         v4 = TO_DOUBLE(epr->tween.v4);
13636         BUF_APPENDF(I4 "transition: CUBIC_BEZIER %.5f %.5f %.5f %.5f %.5f", db, v1, v2, v3, v4);
13637         break;
13638 
13639       default:
13640         no_transition = EINA_TRUE;
13641         break;
13642      }
13643 
13644    if (!no_transition)
13645      {
13646         if (epr->tween.mode & EDJE_TWEEN_MODE_OPT_FROM_CURRENT)
13647           BUF_APPENDF(" CURRENT;\n");
13648         else
13649           BUF_APPENDF(";\n");
13650      }
13651    /* In */
13652    db = epr->in.from;
13653    db2 = epr->in.range;
13654    if (NEQ(db, ZERO) || NEQ(db2, ZERO))
13655      BUF_APPENDF(I4 "in: %.5f %.5f;\n", db, db2);
13656 
13657    /* Targets */
13658    if ((ll = _edje_program_targets_get(obj, epr)))
13659      {
13660         EINA_LIST_FOREACH(ll, l, data)
13661           BUF_APPENDF(I4 "target: \"%s\";\n", data);
13662         edje_edit_string_list_free(ll);
13663      }
13664 
13665    /* Afters */
13666    if ((ll = _edje_program_afters_get(obj, epr)))
13667      {
13668         EINA_LIST_FOREACH(ll, l, data)
13669           BUF_APPENDF(I4 "after: \"%s\";\n", data);
13670         edje_edit_string_list_free(ll);
13671      }
13672 
13673    // TODO Support script {}
13674    /* api */
13675    api_name = eina_stringshare_add(epr->api.name);
13676    api_description = eina_stringshare_add(epr->api.description);
13677 
13678    if (api_name || api_description)
13679      {
13680         if (api_name && api_description)
13681           {
13682              BUF_APPENDF(I4 "api: \"%s\" \"%s\";\n", api_name, api_description);
13683              edje_edit_string_free(api_name);
13684              edje_edit_string_free(api_description);
13685           }
13686         else
13687         if (api_name)
13688           {
13689              BUF_APPENDF(I4 "api: \"%s\" \"\";\n", api_name);
13690              edje_edit_string_free(api_name);
13691           }
13692         else
13693           {
13694              BUF_APPENDF(I4 "api: \"\" \"%s\";\n", api_description);
13695              edje_edit_string_free(api_description);
13696           }
13697      }
13698 
13699    BUF_APPEND(I3 "}\n");
13700    return ret;
13701 }
13702 
13703 static void
_edje_source_with_double_values_append(const char * param_name,char val_num,double val1,double val2,Eina_Strbuf * buf,Eina_Bool * ret_value)13704 _edje_source_with_double_values_append(const char *param_name, char val_num, double val1, double val2, Eina_Strbuf *buf, Eina_Bool *ret_value)
13705 {
13706    Eina_Strbuf *string;
13707    Eina_Bool ret = EINA_TRUE;
13708 
13709    if ((val_num != 1) && (val_num != 2))
13710      {
13711         *ret_value = EINA_FALSE;
13712         return;
13713      }
13714 
13715    string = eina_strbuf_new();
13716    if (param_name)
13717      eina_strbuf_append_printf(string, "%s:", param_name);
13718    eina_strbuf_append_printf(string, " %.2f", val1);
13719    if (val_num == 2)
13720      eina_strbuf_append_printf(string, " %.2f", val2);
13721    eina_strbuf_append(string, ";\n");
13722    BUF_APPEND(eina_strbuf_string_get(string));
13723 
13724    *ret_value = ret;
13725    eina_strbuf_free(string);
13726 }
13727 
13728 #define INHERIT_CHECK(ATTRIBUTE) (pd->ATTRIBUTE != inherit_pd->ATTRIBUTE)
13729 
13730 #define INHERIT_CHECK_DOUBLE(ATTRIBUTE_1, ATTRIBUTE_2) ((NEQ(pd->ATTRIBUTE_1, inherit_pd->ATTRIBUTE_1)) || (NEQ(pd->ATTRIBUTE_2, inherit_pd->ATTRIBUTE_2)))
13731 
13732 #define INHERIT_CHECK_STRING(ATTRIBUTE_STR) (strcmp(inherit_pd->ATTRIBUTE_STR, pd->ATTRIBUTE_STR))
13733 
13734 static void
_edje_generate_source_state_relative(Edje * ed,Edje_Part_Description_Common * pd,Edje_Part_Description_Common * inherit_pd,Eina_Strbuf * buf)13735 _edje_generate_source_state_relative(Edje *ed,
13736                                      Edje_Part_Description_Common *pd,
13737                                      Edje_Part_Description_Common *inherit_pd,
13738                                      Eina_Strbuf *buf)
13739 {
13740 
13741    Eina_Bool ret = EINA_TRUE;
13742    int attr_amount;
13743    int indent_space = strlen(I6);
13744 
13745    Eina_Bool relative = EINA_FALSE;
13746    Eina_Bool offset = EINA_FALSE;
13747    Eina_Bool rel_to = EINA_FALSE;
13748    Eina_Bool rel_to_x = EINA_FALSE;
13749    Eina_Bool rel_to_y = EINA_FALSE;
13750 
13751    if (inherit_pd)
13752      {
13753          relative = !INHERIT_CHECK_DOUBLE(rel1.relative_x, rel1.relative_y) ? EINA_FALSE : EINA_TRUE;
13754          offset = !INHERIT_CHECK_DOUBLE(rel1.offset_x, rel1.offset_y) ? EINA_FALSE : EINA_TRUE;
13755          if ((pd->rel1.id_x != inherit_pd->rel1.id_x) || (pd->rel1.id_y != inherit_pd->rel1.id_y))
13756            {
13757               if (pd->rel1.id_x == inherit_pd->rel1.id_x && pd->rel1.id_y != inherit_pd->rel1.id_y)
13758                 {
13759                    rel_to = 1;
13760                    rel_to_y = 1;
13761                 }
13762               else if (pd->rel1.id_x != inherit_pd->rel1.id_x && pd->rel1.id_y == inherit_pd->rel1.id_y)
13763                 {
13764                    rel_to = 1;
13765                    rel_to_x = 1;
13766                 }
13767               else if (pd->rel1.id_x == pd->rel1.id_y && pd->rel1.id_x != -1)
13768                 {
13769                    rel_to = 1;
13770                    rel_to_x = EINA_FALSE;
13771                    rel_to_y = EINA_FALSE;
13772                 }
13773               else
13774                 {
13775                    rel_to = 2;
13776                    rel_to_x = 1;
13777                    rel_to_y = 1;
13778                 }
13779            }
13780 
13781      }
13782    else
13783      {
13784         relative = (EQ(pd->rel1.relative_x, ZERO) && EQ(pd->rel1.relative_y, ZERO)) ? EINA_FALSE : EINA_TRUE;
13785         offset = ((pd->rel1.offset_x == 0) && (pd->rel1.offset_y == 0)) ? EINA_FALSE : EINA_TRUE;
13786         if ((pd->rel1.id_x != -1) || (pd->rel1.id_y != -1))
13787           {
13788              if (pd->rel1.id_x == -1 && pd->rel1.id_y != -1)
13789                {
13790                   rel_to = 1;
13791                   rel_to_y = 1;
13792                }
13793              else if (pd->rel1.id_x != -1 && pd->rel1.id_y == -1)
13794                {
13795                   rel_to = 1;
13796                   rel_to_x = 1;
13797                }
13798              else if (pd->rel1.id_x == pd->rel1.id_y && pd->rel1.id_x != -1)
13799                {
13800                   rel_to = 1;
13801                   rel_to_x = EINA_FALSE;
13802                   rel_to_y = EINA_FALSE;
13803                }
13804              else
13805                {
13806                   rel_to = 2;
13807                   rel_to_x = 1;
13808                   rel_to_y = 1;
13809                }
13810           }
13811     }
13812 
13813    attr_amount = relative + offset + rel_to;
13814 
13815    indent_space = strlen(I6);
13816    if (attr_amount == 1)
13817      indent_space = 0;
13818 
13819    //Rel1
13820    if (attr_amount)
13821      {
13822         if (attr_amount > 1)
13823           BUF_APPEND(I5 "rel1 {\n");
13824         else
13825           BUF_APPEND(I5 "rel1.");
13826 
13827         if (relative)
13828           {
13829              char relative_str[strlen("relative") + indent_space + 1];
13830              snprintf(relative_str, strlen("relative") + indent_space + 1,
13831                       "%*srelative", indent_space, "");
13832              _edje_source_with_double_values_append(relative_str, 2,
13833                                                   TO_DOUBLE(pd->rel1.relative_x),
13834                                                   TO_DOUBLE(pd->rel1.relative_y),
13835                                                   buf, &ret);
13836           }
13837 
13838         if (offset)
13839           BUF_APPENDF("%*soffset: %d %d;\n", indent_space, "",
13840                       pd->rel1.offset_x, pd->rel1.offset_y);
13841 
13842         if (rel_to != 0)
13843           {
13844             if (rel_to_x == 0 && rel_to_y == 0)
13845               {
13846                  BUF_APPENDF("%*sto: \"%s\";\n", indent_space, "",
13847                              pd->rel1.id_x == -1 ? "" :  ed->table_parts[pd->rel1.id_x]->part->name);
13848               }
13849             if (rel_to_x == 1)
13850               {
13851                  BUF_APPENDF("%*sto_x: \"%s\";\n", indent_space, "",
13852                             pd->rel1.id_x == -1 ? "" :ed->table_parts[pd->rel1.id_x]->part->name);
13853               }
13854 
13855             if (rel_to_y == 1)
13856               {
13857                 BUF_APPENDF("%*sto_y: \"%s\";\n", indent_space, "",
13858                            pd->rel1.id_y == -1 ? "" : ed->table_parts[pd->rel1.id_y]->part->name);
13859              }
13860           }
13861         if (attr_amount > 1)
13862            BUF_APPEND(I5 "}\n");
13863      }
13864 
13865    //Rel 2
13866    relative = EINA_FALSE;
13867    offset = EINA_FALSE;
13868    rel_to = EINA_FALSE;
13869    rel_to_x = EINA_FALSE;
13870    rel_to_y = EINA_FALSE;
13871    if (inherit_pd)
13872      {
13873          relative = !INHERIT_CHECK_DOUBLE(rel2.relative_x, rel2.relative_y) ? EINA_FALSE : EINA_TRUE;
13874          offset = !INHERIT_CHECK_DOUBLE(rel2.offset_x, rel2.offset_y) ? EINA_FALSE : EINA_TRUE;
13875          if ((pd->rel2.id_x != inherit_pd->rel2.id_x) || (pd->rel2.id_y != inherit_pd->rel2.id_y))
13876            {
13877               if (pd->rel2.id_x == inherit_pd->rel2.id_x && pd->rel2.id_y != inherit_pd->rel2.id_y)
13878                 {
13879                    rel_to = 1;
13880                    rel_to_y = 1;
13881                 }
13882               else if (pd->rel2.id_x != inherit_pd->rel2.id_x && pd->rel2.id_y == inherit_pd->rel2.id_y)
13883                 {
13884                    rel_to = 1;
13885                    rel_to_x = 1;
13886                 }
13887               else if (pd->rel2.id_x == pd->rel2.id_y && pd->rel2.id_x != -1)
13888                 {
13889                    rel_to = 1;
13890                    rel_to_x = EINA_FALSE;
13891                    rel_to_y = EINA_FALSE;
13892                 }
13893               else
13894                 {
13895                    rel_to = 2;
13896                    rel_to_x = 1;
13897                    rel_to_y = 1;
13898                 }
13899            }
13900 
13901      }
13902    else
13903      {
13904         relative = (EQ(pd->rel2.relative_x, FROM_INT(1)) && EQ(pd->rel2.relative_y, FROM_INT(1))) ? EINA_FALSE : EINA_TRUE;
13905         offset = ((pd->rel2.offset_x == -1) && (pd->rel2.offset_y == -1)) ? EINA_FALSE : EINA_TRUE;
13906         if ((pd->rel2.id_x != -1) || (pd->rel2.id_y != -1))
13907           {
13908              if (pd->rel2.id_x == -1 && pd->rel2.id_y != -1)
13909                {
13910                   rel_to = 1;
13911                   rel_to_y = 1;
13912                }
13913              else if (pd->rel2.id_x != -1 && pd->rel2.id_y == -1)
13914                {
13915                   rel_to = 1;
13916                   rel_to_x = 1;
13917                }
13918              else if (pd->rel2.id_x == pd->rel2.id_y && pd->rel2.id_x != -1)
13919                {
13920                   rel_to = 1;
13921                   rel_to_x = EINA_FALSE;
13922                   rel_to_y = EINA_FALSE;
13923                }
13924              else
13925                {
13926                   rel_to = 2;
13927                   rel_to_x = 1;
13928                   rel_to_y = 1;
13929                }
13930           }
13931     }
13932 
13933    attr_amount = relative + offset + rel_to;
13934 
13935    indent_space = strlen(I6);
13936    if (attr_amount == 1)
13937      indent_space = 0;
13938 
13939    if (attr_amount)
13940      {
13941         if (attr_amount > 1)
13942           BUF_APPEND(I5 "rel2 {\n");
13943         else
13944           BUF_APPEND(I5 "rel2.");
13945 
13946         if (relative)
13947           {
13948              char relative_str[strlen("relative") + indent_space + 1];
13949              snprintf(relative_str, strlen("relative") + indent_space + 1,
13950                       "%*srelative", indent_space, "");
13951              _edje_source_with_double_values_append(relative_str, 2,
13952                                                   TO_DOUBLE(pd->rel2.relative_x),
13953                                                   TO_DOUBLE(pd->rel2.relative_y),
13954                                                   buf, &ret);
13955           }
13956 
13957         if (offset)
13958           BUF_APPENDF("%*soffset: %d %d;\n", indent_space, "",
13959                       pd->rel2.offset_x, pd->rel2.offset_y);
13960 
13961         if (rel_to != 0)
13962           {
13963             if (rel_to_x == 0 && rel_to_y == 0 )
13964               {
13965                  BUF_APPENDF("%*sto: \"%s\";\n", indent_space, "",
13966                               pd->rel2.id_x == -1 ? "" : ed->table_parts[pd->rel2.id_x]->part->name);
13967               }
13968             if (rel_to_x == 1)
13969               {
13970                  BUF_APPENDF("%*sto_x: \"%s\";\n", indent_space, "",
13971                             pd->rel2.id_x == -1 ? "" : ed->table_parts[pd->rel2.id_x]->part->name);
13972               }
13973 
13974             if (rel_to_y == 1)
13975               {
13976                 BUF_APPENDF("%*sto_y: \"%s\";\n", indent_space, "",
13977                            pd->rel2.id_y == -1 ? "" : ed->table_parts[pd->rel2.id_y]->part->name);
13978              }
13979           }
13980         if (attr_amount > 1)
13981            BUF_APPEND(I5 "}\n");
13982      }
13983 }
13984 
13985 static void
_edje_generate_source_state_image(Edje_Edit * eed,Evas_Object * obj,const char * part,const char * state,double value,Edje_Part_Description_Common * pd,Edje_Part_Description_Common * inherit_pd,Eina_Strbuf * buf)13986 _edje_generate_source_state_image(Edje_Edit *eed, Evas_Object *obj,
13987                                   const char *part, const char *state, double value,
13988                                   Edje_Part_Description_Common *pd,
13989                                   Edje_Part_Description_Common *inherit_pd,
13990                                   Eina_Strbuf *buf)
13991 {
13992    Eina_Bool ret = EINA_TRUE;
13993    Eina_List *l, *ll;
13994    int attr_amount = 0;
13995    int indent_space = strlen(I6);
13996    char *data;
13997    unsigned int i;
13998 
13999    Eina_Bool name = EINA_FALSE;
14000    Eina_Bool border = EINA_FALSE;
14001    Eina_Bool border_scale_by = EINA_FALSE;
14002    Eina_Bool scale_hint = EINA_FALSE;
14003    Eina_Bool border_no_fill = EINA_FALSE;
14004    Eina_Bool border_scale = EINA_FALSE;
14005    Eina_Bool tweens = EINA_FALSE;
14006 
14007    Edje_Part_Description_Image *img;
14008    img = (Edje_Part_Description_Image *)pd;
14009    Edje_Part_Description_Image *inherit_pd_img = (Edje_Part_Description_Image *)inherit_pd;
14010 
14011 
14012    if (inherit_pd)
14013      {
14014         if (img->image.id != -1)
14015           name = (img->image.id == inherit_pd_img->image.id) ? EINA_FALSE : EINA_TRUE;
14016 
14017         border = ((img->image.border.l == inherit_pd_img->image.border.l) &&
14018                   (img->image.border.r == inherit_pd_img->image.border.r) &&
14019                   (img->image.border.t == inherit_pd_img->image.border.t) &&
14020                   (img->image.border.b == inherit_pd_img->image.border.b)) ? EINA_FALSE : EINA_TRUE;
14021 
14022         border_scale_by = EQ(img->image.border.scale_by, inherit_pd_img->image.border.scale_by) ? EINA_FALSE : EINA_TRUE;
14023 
14024         scale_hint = EQ(img->image.scale_hint, inherit_pd_img->image.scale_hint) ? EINA_FALSE : EINA_TRUE;
14025 
14026         border_no_fill = (img->image.border.no_fill == inherit_pd_img->image.border.no_fill) ? EINA_FALSE : EINA_TRUE;
14027 
14028         border_scale = (img->image.border.scale == inherit_pd_img->image.border.scale) ? EINA_FALSE : EINA_TRUE;
14029 
14030         if (img->image.tweens_count == inherit_pd_img->image.tweens_count)
14031           {
14032              for (i = 0; i < img->image.tweens_count; i++)
14033                {
14034                   if (img->image.tweens[i]->id == inherit_pd_img->image.tweens[i]->id)
14035                     continue;
14036                   else
14037                     {
14038                        tweens = EINA_TRUE;
14039                        break;
14040                     }
14041                }
14042           }
14043      }
14044    else
14045      {
14046         name = (img->image.id == -1) ? EINA_FALSE : EINA_TRUE;
14047         border = (img->image.border.l == 0 && img->image.border.r == 0 &&
14048                   img->image.border.t == 0 && img->image.border.b == 0) ? EINA_FALSE : EINA_TRUE;
14049         border_scale_by = EQ(img->image.border.scale_by, ZERO) ? EINA_FALSE : EINA_TRUE;
14050         scale_hint = (img->image.scale_hint == EVAS_IMAGE_SCALE_HINT_NONE) ? EINA_FALSE : EINA_TRUE;
14051         border_no_fill = (img->image.border.no_fill == 0) ? EINA_FALSE : EINA_TRUE;
14052         border_scale = (img->image.border.scale == 0) ? EINA_FALSE : EINA_TRUE;
14053         tweens = (img->image.tweens_count == 0) ? EINA_FALSE : EINA_TRUE;
14054      }
14055 
14056 
14057    attr_amount =  name + border + border_scale_by + scale_hint + border_no_fill + border_scale + tweens;
14058 
14059    if (attr_amount == 0) goto fill;
14060    if (attr_amount == 1)
14061      indent_space = 0;
14062 
14063    if (attr_amount > 1)
14064       BUF_APPEND(I5 "image {\n");
14065    else
14066       BUF_APPEND(I5 "image.");
14067 
14068    if (name)
14069      {
14070         if (img->image.set)
14071           {
14072              BUF_APPENDF("%*snormal: \"%s\";\n", indent_space, "", _edje_set_name_find(eed, img->image.id));
14073           }
14074         else
14075           {
14076              BUF_APPENDF("%*snormal: \"%s\";\n", indent_space, "", _edje_image_name_find(eed, img->image.id));
14077           }
14078      }
14079 
14080    if (tweens)
14081      {
14082         ll = edje_edit_state_tweens_list_get(obj, part, state, value);
14083         EINA_LIST_FOREACH(ll, l, data)
14084            BUF_APPENDF("%*stween: \"%s\";\n", indent_space, "", data);
14085         edje_edit_string_list_free(ll);
14086      }
14087 
14088    if (border)
14089      BUF_APPENDF("%*sborder: %d %d %d %d;\n", indent_space, "",
14090                  img->image.border.l, img->image.border.r,
14091                  img->image.border.t, img->image.border.b);
14092 
14093    if (border_scale_by)
14094      {
14095         char border_scale_by_str[strlen("border_scale_by") + indent_space + 1];
14096         snprintf(border_scale_by_str, strlen("border_scale_by") + indent_space + 1,
14097                       "%*sborder_scale_by", indent_space, "");
14098         _edje_source_with_double_values_append(border_scale_by_str, 1,
14099                                               TO_DOUBLE(img->image.border.scale_by),
14100                                               0.0, buf, &ret);
14101      }
14102 
14103    if (border_scale)
14104      BUF_APPENDF("%*sborder_scale: 1;\n", indent_space, "");
14105 
14106    if (scale_hint && img->image.scale_hint == EVAS_IMAGE_SCALE_HINT_DYNAMIC)
14107      {
14108         BUF_APPENDF("%*sscale_hint: DYNAMIC;\n", indent_space, "");
14109      }
14110    else if (scale_hint && img->image.scale_hint == EVAS_IMAGE_SCALE_HINT_STATIC)
14111      {
14112         BUF_APPENDF("%*sscale_hint: STATIC;\n", indent_space, "");
14113      }
14114 
14115    if (border_no_fill && img->image.border.no_fill == 1)
14116      {
14117        BUF_APPENDF("%*smiddle: NONE;\n", indent_space, "");
14118      }
14119    else if (border_no_fill && img->image.border.no_fill == 2)
14120      {
14121        BUF_APPENDF("%*smiddle: SOLID;\n", indent_space, "");
14122      }
14123 
14124    if (attr_amount > 1)
14125      BUF_APPEND(I5 "}\n"); //image
14126 
14127    //Fill
14128 fill:
14129    attr_amount = 0;
14130    int attr_orig_amount = 0;
14131    int attr_size_amount = 0;
14132 
14133    Eina_Bool smooth = EINA_FALSE;
14134    Eina_Bool type = EINA_FALSE;
14135    Eina_Bool orig_rel = EINA_FALSE;
14136    Eina_Bool orig_abs = EINA_FALSE;
14137    Eina_Bool size_rel = EINA_FALSE;
14138    Eina_Bool size_abs = EINA_FALSE;
14139 
14140    if (inherit_pd_img)
14141      {
14142         smooth = (inherit_pd_img->image.fill.smooth == img->image.fill.smooth) ? EINA_FALSE : EINA_TRUE;
14143         type = (inherit_pd_img->image.fill.type == img->image.fill.type) ? EINA_FALSE : EINA_TRUE;
14144         orig_rel = (EQ(inherit_pd_img->image.fill.pos_rel_x, img->image.fill.pos_rel_x) &&
14145                     EQ(inherit_pd_img->image.fill.pos_rel_y, img->image.fill.pos_rel_y)) ? EINA_FALSE : EINA_TRUE;
14146         orig_abs = ((inherit_pd_img->image.fill.pos_abs_x == img->image.fill.pos_abs_x) &&
14147                     (inherit_pd_img->image.fill.pos_abs_y == img->image.fill.pos_abs_y)) ? EINA_FALSE : EINA_TRUE;
14148 
14149         size_rel = (EQ(inherit_pd_img->image.fill.rel_x, img->image.fill.rel_x) &&
14150                     EQ(inherit_pd_img->image.fill.rel_y, img->image.fill.rel_y)) ? EINA_FALSE : EINA_TRUE;
14151         size_abs = ((inherit_pd_img->image.fill.abs_x == img->image.fill.abs_x) &&
14152                     (inherit_pd_img->image.fill.abs_y == img->image.fill.abs_y)) ? EINA_FALSE : EINA_TRUE;
14153      }
14154    else
14155      {
14156         smooth = (img->image.fill.smooth == 1) ? EINA_FALSE : EINA_TRUE;
14157         type = (img->image.fill.type == EDJE_FILL_TYPE_SCALE) ? EINA_FALSE : EINA_TRUE;
14158         orig_rel = (EQ(img->image.fill.pos_rel_x, ZERO) && EQ(img->image.fill.pos_rel_y, ZERO)) ? EINA_FALSE : EINA_TRUE;
14159         orig_abs = ((img->image.fill.pos_abs_x == 0) && (img->image.fill.pos_abs_y == 0)) ? EINA_FALSE : EINA_TRUE;
14160         size_rel = (EQ(img->image.fill.rel_x, FROM_INT(1)) && EQ(img->image.fill.rel_y, FROM_INT(1))) ? EINA_FALSE : EINA_TRUE;
14161         size_abs = ((img->image.fill.abs_x == 0) && (img->image.fill.abs_y == 0)) ? EINA_FALSE : EINA_TRUE;
14162      }
14163 
14164    attr_orig_amount = orig_rel + orig_abs;
14165    attr_size_amount = size_rel + size_abs;
14166    attr_amount = smooth + type + attr_orig_amount + attr_size_amount;
14167 
14168    if (attr_amount == 0) return;
14169 
14170    indent_space = 0;
14171    if (attr_amount > 1 || attr_size_amount || attr_orig_amount)
14172      indent_space = strlen(I6);
14173 
14174    if (attr_amount)
14175      {
14176        if (attr_amount > 1 || attr_size_amount || attr_orig_amount)
14177          BUF_APPEND(I5 "fill {\n");
14178        else
14179          BUF_APPEND(I5 "fill.");
14180 
14181        if (smooth)
14182          BUF_APPENDF("%*ssmooth: 0;\n", indent_space, "");
14183 
14184        if (type)
14185          BUF_APPENDF("%*stype: TILE;\n", indent_space, "");
14186 
14187        if (attr_orig_amount)
14188          {
14189            indent_space = 0;
14190            if (attr_orig_amount > 1)
14191              indent_space = strlen(I7);
14192            if (attr_orig_amount > 1)
14193              BUF_APPEND(I6 "origin {\n");
14194            else
14195              BUF_APPEND(I6 "origin.");
14196 
14197            if (orig_rel)
14198              {
14199                char relative[strlen("relative") + indent_space + 1];
14200                snprintf(relative, strlen("relative") + indent_space + 1,
14201                         "%*srelative", indent_space, "");
14202                _edje_source_with_double_values_append(relative, 2,
14203                         TO_DOUBLE(img->image.fill.pos_rel_x),
14204                         TO_DOUBLE(img->image.fill.pos_rel_y),
14205                         buf, &ret);
14206              }
14207 
14208            if (orig_abs)
14209              BUF_APPENDF("%*soffset: %d %d;\n", indent_space, "",
14210                          img->image.fill.pos_abs_x, img->image.fill.pos_abs_y);
14211 
14212             if (attr_orig_amount > 1)
14213               BUF_APPEND(I6 "}\n");
14214          }
14215 
14216        if (attr_size_amount)
14217          {
14218            indent_space = 0;
14219            if (attr_size_amount > 1)
14220              indent_space = strlen(I7);
14221 
14222            if (attr_size_amount > 1)
14223              BUF_APPEND(I6 "size {\n");
14224            else
14225              BUF_APPEND(I6 "size.");
14226 
14227            if (size_rel)
14228              {
14229                char relative[strlen("relative") + indent_space + 1];
14230                snprintf(relative, strlen("relative") + indent_space + 1,
14231                         "%*srelative", indent_space, "");
14232                _edje_source_with_double_values_append(relative, 2,
14233                         TO_DOUBLE(img->image.fill.rel_x),
14234                         TO_DOUBLE(img->image.fill.rel_y),
14235                         buf, &ret);
14236              }
14237 
14238            if (size_abs)
14239              BUF_APPENDF("%*soffset: %d %d;\n", indent_space, "",
14240                          img->image.fill.abs_x, img->image.fill.abs_y);
14241 
14242            if (attr_size_amount > 1)
14243              BUF_APPEND(I6 "}\n");
14244          }
14245 
14246        if (attr_amount > 1 || attr_size_amount || attr_orig_amount)
14247          BUF_APPEND(I5 "}\n");
14248     }
14249 }
14250 
14251 static void
_edje_generate_source_state_map(Edje * ed,Edje_Part_Description_Common * pd,Edje_Part_Description_Common * inherit_pd,Eina_Strbuf * buf)14252 _edje_generate_source_state_map(Edje *ed,
14253                                 Edje_Part_Description_Common *pd,
14254                                 Edje_Part_Description_Common *inherit_pd,
14255                                 Eina_Strbuf *buf)
14256 {
14257    int attr_amount = 0;
14258    int attr_rotate_amount = 0;
14259    int indent_space = 0;
14260    unsigned int i = 0;
14261    Eina_Bool ret = EINA_FALSE;
14262 
14263    Eina_Bool persp = EINA_FALSE;
14264    Eina_Bool light = EINA_FALSE;
14265    Eina_Bool colors_count = EINA_FALSE;
14266    Eina_Bool backcull = EINA_FALSE;
14267    Eina_Bool on = EINA_FALSE;
14268    Eina_Bool persp_on = EINA_FALSE;
14269    Eina_Bool smooth = EINA_FALSE;
14270    Eina_Bool alpha = EINA_FALSE;
14271    Eina_Bool center = 0, x = 0, y = 0, z = EINA_FALSE;
14272 
14273    if (inherit_pd)
14274      {
14275         persp = (inherit_pd->map.id_persp == pd->map.id_persp) ? EINA_FALSE : EINA_TRUE;
14276         light = (inherit_pd->map.id_light == pd->map.id_light) ? EINA_FALSE : EINA_TRUE;
14277         colors_count = (inherit_pd->map.colors_count == pd->map.colors_count) ? EINA_FALSE : EINA_TRUE;
14278         backcull = (inherit_pd->map.backcull == pd->map.backcull) ? EINA_FALSE : EINA_TRUE;
14279         on = (inherit_pd->map.on == pd->map.on) ? EINA_FALSE : EINA_TRUE;
14280         persp_on = (inherit_pd->map.persp_on == pd->map.persp_on) ? EINA_FALSE : EINA_TRUE;
14281         smooth = (inherit_pd->map.smooth == pd->map.smooth) ? EINA_FALSE : EINA_TRUE;
14282         alpha = (inherit_pd->map.alpha == pd->map.alpha) ? EINA_FALSE : EINA_TRUE;
14283 
14284         center = (inherit_pd->map.rot.id_center == pd->map.rot.id_center) ? EINA_FALSE : EINA_TRUE;
14285         x = EQ(inherit_pd->map.rot.x, pd->map.rot.x) ? EINA_FALSE : EINA_TRUE;
14286         y = EQ(inherit_pd->map.rot.y, pd->map.rot.y) ? EINA_FALSE : EINA_TRUE;
14287         z = EQ(inherit_pd->map.rot.z, pd->map.rot.z) ? EINA_FALSE : EINA_TRUE;
14288      }
14289    else
14290      {
14291         persp = (pd->map.id_persp == -1) ? EINA_FALSE : EINA_TRUE;
14292         light = (pd->map.id_light == -1) ? EINA_FALSE : EINA_TRUE;
14293         colors_count = (pd->map.colors_count == 0) ? EINA_FALSE : EINA_TRUE;
14294         backcull = (pd->map.backcull == EINA_FALSE) ? EINA_FALSE : EINA_TRUE;
14295         on = (pd->map.on == EINA_FALSE) ? EINA_FALSE : EINA_TRUE;
14296         persp_on = (pd->map.persp_on == EINA_FALSE) ? EINA_FALSE : EINA_TRUE;
14297         smooth = (pd->map.smooth == EINA_TRUE) ? EINA_FALSE : EINA_TRUE;
14298         alpha = (pd->map.alpha == EINA_TRUE) ? EINA_FALSE : EINA_TRUE;
14299 
14300         center = (pd->map.rot.id_center == -1) ? EINA_FALSE : EINA_TRUE;
14301         x = EQ(pd->map.rot.x, ZERO) ? EINA_FALSE : EINA_TRUE;
14302         y = EQ(pd->map.rot.y, ZERO) ? EINA_FALSE : EINA_TRUE;
14303         z = EQ(pd->map.rot.z, ZERO) ? EINA_FALSE : EINA_TRUE;
14304      }
14305 
14306    attr_amount  = persp + light + colors_count + backcull + on + persp_on + smooth + alpha;
14307    attr_rotate_amount = center + x + y + z;
14308 
14309    if (attr_rotate_amount > 0)
14310      attr_amount += 2;
14311 
14312    if (attr_amount == 0) return;
14313 
14314    if (attr_amount > 1)
14315      indent_space = strlen(I6);
14316 
14317    if (attr_amount)
14318      {
14319         if (attr_amount > 1)
14320           BUF_APPEND(I5 "map {\n");
14321         else
14322           BUF_APPEND(I5 "map.");
14323 
14324         if (persp)
14325           BUF_APPENDF("%*sperspective: \"%s\";\n", indent_space, "",
14326                       (_edje_part_name_find(ed, pd->map.id_persp) == NULL ? "" : _edje_part_name_find(ed, pd->map.id_persp)));
14327 
14328         if (light)
14329           BUF_APPENDF("%*slight: \"%s\";\n", indent_space, "",
14330                       _edje_part_name_find(ed, pd->map.id_light));
14331 
14332         if (backcull)
14333           BUF_APPENDF("%*sbackface_cull: 1;\n", indent_space, "");
14334 
14335         if (on)
14336           BUF_APPENDF("%*son: 1;\n", indent_space, "");
14337 
14338         if (persp_on)
14339           BUF_APPENDF("%*sperspective_on: 1;\n", indent_space, "");
14340 
14341         if (smooth)
14342           BUF_APPENDF("%*ssmooth: 0;\n", indent_space, "");
14343 
14344         if (alpha)
14345           BUF_APPENDF("%*salpha: 0;\n", indent_space, "");
14346 
14347         if (colors_count)
14348           {
14349              for (i = 0; i < pd->map.colors_count; ++i)
14350                {
14351                   if ((pd->map.colors[i]->r != 255) || (pd->map.colors[i]->g != 255) ||
14352                       (pd->map.colors[i]->b != 255) || (pd->map.colors[i]->a != 255))
14353                     BUF_APPENDF(I6 "color: %d %d %d %d %d;\n", pd->map.colors[i]->idx,
14354                                 pd->map.colors[i]->r, pd->map.colors[i]->g,
14355                                 pd->map.colors[i]->b, pd->map.colors[i]->a);
14356                }
14357           }
14358 
14359         if (attr_rotate_amount)
14360           {
14361              if (attr_rotate_amount > 1)
14362                {
14363                  BUF_APPEND(I6 "rotation {\n");
14364                  indent_space = strlen(I7);
14365                }
14366              else
14367                {
14368                   BUF_APPENDF(I6 "rotation.");
14369                   indent_space = 0;
14370                }
14371 
14372              if (center)
14373                BUF_APPENDF("%*scenter: \"%s\";\n", indent_space, "",
14374                            (_edje_part_name_find(ed, pd->map.rot.id_center) == NULL ? "" :
14375                             _edje_part_name_find(ed, pd->map.rot.id_center)));
14376 
14377              if (x)
14378                {
14379                  char rot_x[strlen("x") + indent_space + 1];
14380                  snprintf(rot_x, strlen("x") + indent_space + 1,
14381                           "%*sx", indent_space, "");
14382                  _edje_source_with_double_values_append(rot_x, 1,
14383                                                    TO_DOUBLE(pd->map.rot.x),
14384                                                    0.0, buf, &ret);
14385                }
14386              if (y)
14387                {
14388                  char rot_y[strlen("y") + indent_space + 1];
14389                  snprintf(rot_y, strlen("y") + indent_space + 1,
14390                           "%*sy", indent_space, "");
14391                  _edje_source_with_double_values_append(rot_y, 1,
14392                                                    TO_DOUBLE(pd->map.rot.y),
14393                                                    0.0, buf, &ret);
14394                }
14395              if (z)
14396                {
14397                  char rot_z[strlen("z") + indent_space + 1];
14398                  snprintf(rot_z, strlen("z") + indent_space + 1,
14399                           "%*sz", indent_space, "");
14400                  _edje_source_with_double_values_append(rot_z, 1,
14401                                                     TO_DOUBLE(pd->map.rot.z),
14402                                                     0.0, buf, &ret);
14403                }
14404 
14405              if (attr_rotate_amount > 1)
14406                BUF_APPEND(I6 "}\n");
14407           }
14408 
14409         if (attr_amount > 1)
14410           BUF_APPEND(I5 "}\n");
14411      }
14412 }
14413 
14414 static void
_edje_generate_source_state_proxy(Edje * ed,Edje_Part_Description_Common * pd,Edje_Part_Description_Common * inherit_pd,Eina_Strbuf * buf)14415 _edje_generate_source_state_proxy(Edje *ed, Edje_Part_Description_Common *pd,
14416                                   Edje_Part_Description_Common *inherit_pd,
14417                                   Eina_Strbuf *buf)
14418 {
14419    int attr_amount = 0;
14420    int indent_space = 0;
14421    Eina_Bool ret = 1;
14422    Edje_Part_Description_Proxy *pro = (Edje_Part_Description_Proxy *)pd;
14423    Edje_Part_Description_Proxy *inherit_pd_pro = (Edje_Part_Description_Proxy *) inherit_pd;
14424 
14425    int source_visible = EINA_FALSE;
14426    int source_clip = EINA_FALSE;
14427    int source = EINA_FALSE;
14428 
14429    if (inherit_pd_pro)
14430      {
14431         source = (inherit_pd_pro->proxy.id == pro->proxy.id) ? EINA_FALSE : EINA_TRUE;
14432 
14433         source_visible = (inherit_pd_pro->proxy.source_visible == pro->proxy.source_visible) ? EINA_FALSE : EINA_TRUE;
14434         source_clip = (inherit_pd_pro->proxy.source_clip == pro->proxy.source_clip) ? EINA_FALSE : EINA_TRUE;
14435      }
14436    else
14437      {
14438         source = (pro->proxy.id == -1) ? EINA_FALSE : EINA_TRUE;
14439         source_visible = (pro->proxy.source_visible == 1) ? EINA_FALSE : EINA_TRUE;
14440         source_clip = (pro->proxy.source_clip == 1) ? EINA_FALSE : EINA_TRUE;
14441      }
14442 
14443    if (source)
14444      BUF_APPENDF(I5 "source: \"%s\";\n", (pro->proxy.id >= 0) ? _edje_part_name_find(ed, pro->proxy.id) : "");
14445 
14446    attr_amount = source_visible + source_clip;
14447    if (!attr_amount) goto fill_proxy;
14448    if (attr_amount > 1)
14449      indent_space = strlen(I6);
14450 
14451    //Proxy block
14452    if (attr_amount)
14453      {
14454         if (attr_amount > 1)
14455           BUF_APPEND(I5 "proxy {\n");
14456         else
14457           BUF_APPEND(I5 "proxy.");
14458 
14459         if (source_visible)
14460           BUF_APPENDF("%*ssource_visible: 0;\n", indent_space, "");
14461 
14462         if (source_clip)
14463           BUF_APPENDF("%*ssource_clip: 0;\n", indent_space, "");
14464 
14465         if (attr_amount > 1)
14466           BUF_APPEND(I5 "}\n");
14467      }
14468 
14469 fill_proxy:
14470    attr_amount = 0;
14471 
14472    //Fill
14473    int attr_orig_amount = 0;
14474    int attr_size_amount = 0;
14475 
14476    Eina_Bool smooth = EINA_FALSE;
14477    Eina_Bool type = EINA_FALSE;
14478    Eina_Bool orig_rel = EINA_FALSE;
14479    Eina_Bool orig_abs = EINA_FALSE;
14480    Eina_Bool size_rel = EINA_FALSE;
14481    Eina_Bool size_abs = EINA_FALSE;
14482 
14483    if (inherit_pd_pro)
14484      {
14485         smooth = (inherit_pd_pro->proxy.fill.smooth == pro->proxy.fill.smooth) ? EINA_FALSE : EINA_TRUE;
14486         type = (inherit_pd_pro->proxy.fill.type == pro->proxy.fill.type) ? EINA_FALSE : EINA_TRUE;
14487         orig_rel = (EQ(inherit_pd_pro->proxy.fill.pos_rel_x, pro->proxy.fill.pos_rel_x) &&
14488                     EQ(inherit_pd_pro->proxy.fill.pos_rel_y, pro->proxy.fill.pos_rel_y)) ? EINA_FALSE : EINA_TRUE;
14489         orig_abs = ((inherit_pd_pro->proxy.fill.pos_abs_x == pro->proxy.fill.pos_abs_x) &&
14490                     (inherit_pd_pro->proxy.fill.pos_abs_y == pro->proxy.fill.pos_abs_y)) ? EINA_FALSE : EINA_TRUE;
14491 
14492         size_rel = (EQ(inherit_pd_pro->proxy.fill.rel_x, pro->proxy.fill.rel_x) &&
14493                     EQ(inherit_pd_pro->proxy.fill.rel_y, pro->proxy.fill.rel_y)) ? EINA_FALSE : EINA_TRUE;
14494         size_abs = ((inherit_pd_pro->proxy.fill.abs_x == pro->proxy.fill.abs_x) &&
14495                     (inherit_pd_pro->proxy.fill.abs_y == pro->proxy.fill.abs_y)) ? EINA_FALSE : EINA_TRUE;
14496      }
14497    else
14498      {
14499         smooth = (pro->proxy.fill.smooth == 1) ? EINA_FALSE : EINA_TRUE;
14500         type = (pro->proxy.fill.type == EDJE_FILL_TYPE_SCALE) ? EINA_FALSE : EINA_TRUE;
14501         orig_rel = (EQ(pro->proxy.fill.pos_rel_x, ZERO) && EQ(pro->proxy.fill.pos_rel_y, ZERO)) ? EINA_FALSE : EINA_TRUE;
14502         orig_abs = ((pro->proxy.fill.pos_abs_x == 0) && (pro->proxy.fill.pos_abs_y == 0)) ? EINA_FALSE : EINA_TRUE;
14503         size_rel = (EQ(pro->proxy.fill.rel_x, FROM_INT(1)) && EQ(pro->proxy.fill.rel_y, FROM_INT(1))) ? EINA_FALSE : EINA_TRUE;
14504         size_abs = ((pro->proxy.fill.abs_x == 0) && (pro->proxy.fill.abs_y == 0)) ? EINA_FALSE : EINA_TRUE;
14505      }
14506 
14507    attr_orig_amount = orig_rel + orig_abs;
14508    attr_size_amount = size_rel + size_abs;
14509    attr_amount = smooth + type + attr_orig_amount + attr_size_amount;
14510 
14511    if (attr_amount == 0) return;
14512 
14513    indent_space = 0;
14514    if (attr_amount > 1 || attr_size_amount || attr_orig_amount)
14515      indent_space = strlen(I6);
14516 
14517    if (attr_amount)
14518      {
14519        if (attr_amount > 1 || attr_size_amount || attr_orig_amount)
14520          BUF_APPEND(I5 "fill {\n");
14521        else
14522          BUF_APPEND(I5 "fill.");
14523 
14524        if (smooth)
14525          BUF_APPENDF("%*ssmooth: 0;\n", indent_space, "");
14526 
14527        if (type)
14528          BUF_APPENDF("%*stype: TILE;\n", indent_space, "");
14529 
14530        if (attr_orig_amount)
14531          {
14532            indent_space = 0;
14533            if (attr_orig_amount > 1)
14534              indent_space = strlen(I7);
14535            if (attr_orig_amount > 1)
14536              BUF_APPEND(I6 "origin {\n");
14537            else
14538              BUF_APPEND(I6 "origin.");
14539 
14540            if (orig_rel)
14541              {
14542                char relative[strlen("relative") + indent_space + 1];
14543                snprintf(relative, strlen("relative") + indent_space + 1,
14544                         "%*srelative", indent_space, "");
14545                _edje_source_with_double_values_append(relative, 2,
14546                         TO_DOUBLE(pro->proxy.fill.pos_rel_x),
14547                         TO_DOUBLE(pro->proxy.fill.pos_rel_y),
14548                         buf, &ret);
14549              }
14550 
14551            if (orig_abs)
14552              BUF_APPENDF("%*soffset: %d %d;\n", indent_space, "",
14553                          pro->proxy.fill.pos_abs_x, pro->proxy.fill.pos_abs_y);
14554 
14555             if (attr_orig_amount > 1)
14556               BUF_APPEND(I6 "}\n");
14557          }
14558 
14559        if (attr_size_amount)
14560          {
14561            indent_space = 0;
14562            if (attr_size_amount > 1)
14563              indent_space = strlen(I7);
14564 
14565            if (attr_size_amount > 1)
14566              BUF_APPEND(I6 "size {\n");
14567            else
14568              BUF_APPEND(I6 "size.");
14569 
14570            if (size_rel)
14571              {
14572                char relative[strlen("relative") + indent_space + 1];
14573                snprintf(relative, strlen("relative") + indent_space + 1,
14574                         "%*srelative", indent_space, "");
14575                _edje_source_with_double_values_append(relative, 2,
14576                         TO_DOUBLE(pro->proxy.fill.rel_x),
14577                         TO_DOUBLE(pro->proxy.fill.rel_y),
14578                         buf, &ret);
14579              }
14580 
14581            if (size_abs)
14582              BUF_APPENDF("%*soffset: %d %d;\n", indent_space, "",
14583                          pro->proxy.fill.abs_x, pro->proxy.fill.abs_y);
14584 
14585            if (attr_size_amount > 1)
14586              BUF_APPEND(I6 "}\n");
14587          }
14588 
14589        if (attr_amount > 1 || attr_size_amount || attr_orig_amount)
14590          BUF_APPEND(I5 "}\n");
14591     }
14592 }
14593 
14594 static void
_edje_generate_source_state_table(Edje_Part_Description_Common * pd,Edje_Part_Description_Common * inherit_pd,Eina_Strbuf * buf)14595 _edje_generate_source_state_table(Edje_Part_Description_Common *pd,
14596                                   Edje_Part_Description_Common *inherit_pd,
14597                                   Eina_Strbuf *buf)
14598 {
14599    int attr_amount = 0;
14600    int indent_space = 0;
14601    Eina_Bool ret = EINA_FALSE;
14602 
14603    Edje_Part_Description_Table *table = (Edje_Part_Description_Table *)pd;
14604    Edje_Part_Description_Table *inherit_pd_table = (Edje_Part_Description_Table *) inherit_pd;
14605 
14606    Eina_Bool homogeneous = EINA_FALSE;
14607    Eina_Bool align = EINA_FALSE;
14608    Eina_Bool padding = EINA_FALSE;
14609    Eina_Bool min = EINA_FALSE;
14610 
14611    if (inherit_pd_table)
14612      {
14613         homogeneous = (inherit_pd_table->table.homogeneous == table->table.homogeneous) ? EINA_FALSE : EINA_TRUE;
14614 
14615         align = (EQ(inherit_pd_table->table.align.x, table->table.align.x) &&
14616                  EQ(inherit_pd_table->table.align.y, table->table.align.y)) ? EINA_FALSE : EINA_TRUE;
14617 
14618         padding = ((inherit_pd_table->table.padding.x == table->table.padding.x) &&
14619                    (inherit_pd_table->table.padding.y == table->table.padding.y)) ? EINA_FALSE : EINA_TRUE;
14620 
14621         min = ((inherit_pd_table->table.min.h == table->table.min.h) &&
14622                (inherit_pd_table->table.min.v == table->table.min.v)) ? EINA_FALSE : EINA_TRUE;
14623      }
14624    else
14625      {
14626         homogeneous = (table->table.homogeneous == EDJE_OBJECT_TABLE_HOMOGENEOUS_NONE) ? EINA_FALSE : EINA_TRUE;
14627         align = (EQ(table->table.align.x, FROM_DOUBLE(0.5)) && EQ(table->table.align.y, FROM_DOUBLE(0.5))) ? EINA_FALSE : EINA_TRUE;
14628         padding = (table->table.padding.x == 0 && table->table.padding.y == 0) ? EINA_FALSE : EINA_TRUE;
14629         min = (table->table.min.h == 0 && table->table.min.v == 0) ? EINA_FALSE : EINA_TRUE;
14630      }
14631 
14632    attr_amount = homogeneous + align + padding + min;
14633 
14634    if (attr_amount == 0) return;
14635 
14636    if (attr_amount > 1)
14637      indent_space = strlen(I6);
14638 
14639    if (attr_amount)
14640      {
14641         if (attr_amount > 1)
14642           BUF_APPEND(I5 "table {\n");
14643         else
14644           BUF_APPEND(I5 "table.");
14645 
14646         switch (table->table.homogeneous)
14647           {
14648            case EDJE_OBJECT_TABLE_HOMOGENEOUS_TABLE:
14649            {
14650               BUF_APPENDF("%*shomogeneous: TABLE;\n", indent_space, "");
14651               break;
14652            }
14653 
14654            case EDJE_OBJECT_TABLE_HOMOGENEOUS_ITEM:
14655            {
14656               BUF_APPENDF("%*shomogeneous: ITEM;\n", indent_space, "");
14657               break;
14658            }
14659           }
14660 
14661         if (align)
14662           {
14663              char align_str[strlen("align") + indent_space + 1];
14664              snprintf(align_str, strlen("align") + indent_space + 1,
14665                       "%*salign", indent_space, "");
14666              _edje_source_with_double_values_append(align_str, 2,
14667                                      TO_DOUBLE(table->table.align.x),
14668                                      TO_DOUBLE(table->table.align.y),
14669                                      buf, &ret);
14670           }
14671 
14672         if (padding)
14673           BUF_APPENDF("%*spadding: %d %d;\n", indent_space, "",
14674                       table->table.padding.x, table->table.padding.y);
14675 
14676         if (min)
14677           BUF_APPENDF("%*smin: %d %d;\n", indent_space, "",
14678                       table->table.min.h, table->table.min.v);
14679 
14680         if (attr_amount > 1)
14681           BUF_APPEND(I5 "}\n");
14682    }
14683 }
14684 
14685 static void
_edje_generate_source_state_box(Edje_Part_Description_Common * pd,Edje_Part_Description_Common * inherit_pd,Eina_Strbuf * buf)14686 _edje_generate_source_state_box(Edje_Part_Description_Common *pd,
14687                                 Edje_Part_Description_Common *inherit_pd,
14688                                 Eina_Strbuf *buf)
14689 {
14690    int attr_amount = 0;
14691    int indent_space = 0;
14692    Eina_Bool ret = EINA_FALSE;
14693 
14694    Edje_Part_Description_Box *box = (Edje_Part_Description_Box *)pd;
14695    Edje_Part_Description_Box *inherit_pd_box = (Edje_Part_Description_Box *)inherit_pd;
14696 
14697    Eina_Bool alt_layout = EINA_FALSE;
14698    Eina_Bool layout = EINA_FALSE;
14699    Eina_Bool align = EINA_FALSE;
14700    Eina_Bool padding = EINA_FALSE;
14701    Eina_Bool min = EINA_FALSE;
14702 
14703    if (inherit_pd_box)
14704      {
14705         layout = ((inherit_pd_box->box.layout != NULL && box->box.layout != NULL &&
14706                   !strcmp(inherit_pd_box->box.layout, box->box.layout)) ||
14707                   (inherit_pd_box->box.layout == NULL && box->box.layout == NULL)) ? EINA_FALSE : EINA_TRUE;
14708 
14709         alt_layout = ((inherit_pd_box->box.alt_layout != NULL && box->box.alt_layout != NULL &&
14710                       !strcmp(inherit_pd_box->box.alt_layout, box->box.alt_layout)) ||
14711                       (inherit_pd_box->box.alt_layout == NULL && box->box.alt_layout == NULL)) ? EINA_FALSE : EINA_TRUE;
14712 
14713         align = (EQ(inherit_pd_box->box.align.x, box->box.align.x) &&
14714                  EQ(inherit_pd_box->box.align.y, box->box.align.y)) ? EINA_FALSE : EINA_TRUE;
14715 
14716         padding = ((inherit_pd_box->box.padding.x == box->box.padding.x) &&
14717                    (inherit_pd_box->box.padding.y == box->box.padding.y)) ? EINA_FALSE : EINA_TRUE;
14718 
14719         min = ((inherit_pd_box->box.min.h == box->box.min.h) &&
14720                (inherit_pd_box->box.min.v == box->box.min.v)) ? EINA_FALSE : EINA_TRUE;
14721      }
14722    else
14723      {
14724         layout = (box->box.layout == NULL) ? EINA_FALSE : EINA_TRUE;
14725         alt_layout = (box->box.alt_layout == NULL) ? EINA_FALSE : EINA_TRUE;
14726         align = EQ(box->box.align.x, FROM_DOUBLE(0.5)) && EQ(box->box.align.y, FROM_DOUBLE(0.5)) ? EINA_FALSE : EINA_TRUE;
14727         padding = (box->box.padding.x == 0 && box->box.padding.y == 0) ? EINA_FALSE : EINA_TRUE;
14728         min =  (box->box.min.h == 0 && box->box.min.v == 0) ? EINA_FALSE : EINA_TRUE;
14729      }
14730 
14731    attr_amount = (layout || alt_layout) + align + padding + min;
14732 
14733    if (attr_amount == 0) return;
14734 
14735    if (attr_amount > 1)
14736      indent_space = strlen(I6);
14737 
14738    if (attr_amount)
14739     {
14740        if (attr_amount > 1)
14741          BUF_APPEND(I5 "box {\n");
14742        else
14743          BUF_APPEND(I5 "box.");
14744 
14745         if (layout && alt_layout)
14746           BUF_APPENDF("%*slayout: \"%s\" \"%s\";\n", indent_space, "",
14747                       box->box.layout, box->box.alt_layout);
14748         else if (!layout && alt_layout)
14749           BUF_APPENDF("%*slayout: \"horizontal\" \"%s\";\n", indent_space, "",
14750                       box->box.alt_layout);
14751         else if (layout && !alt_layout)
14752           BUF_APPENDF("%*slayout: \"%s\";\n", indent_space, "",
14753                       box->box.layout);
14754 
14755         if (align)
14756           {
14757              char align_str[strlen("align") + indent_space + 1];
14758              snprintf(align_str, strlen("align") + indent_space + 1,
14759                       "%*salign", indent_space, "");
14760              _edje_source_with_double_values_append(align_str, 2,
14761                                     TO_DOUBLE(box->box.align.x),
14762                                     TO_DOUBLE(box->box.align.y),
14763                                     buf, &ret);
14764           }
14765 
14766         if (padding)
14767           BUF_APPENDF("%*spadding: %d %d;\n", indent_space, "",
14768                       box->box.padding.x, box->box.padding.y);
14769 
14770         if (min)
14771           BUF_APPENDF("%*smin: %d %d;\n", indent_space, "",
14772                       box->box.min.h, box->box.min.v);
14773 
14774         if (attr_amount > 1)
14775           BUF_APPEND(I5 "}\n");
14776    }
14777 }
14778 
14779 static void
_edje_generate_source_state_text(Edje * ed,Edje_Part_Description_Common * pd,Edje_Part_Description_Common * inherit_pd,Eina_Strbuf * buf)14780 _edje_generate_source_state_text(Edje *ed, Edje_Part_Description_Common *pd,
14781                                  Edje_Part_Description_Common *inherit_pd,
14782                                  Eina_Strbuf *buf)
14783 {
14784    int attr_amount = 0;
14785    int indent_space = 0;
14786    Eina_Bool ret = EINA_TRUE;
14787 
14788    Eina_Bool color_3 = EINA_FALSE;
14789    Eina_Bool domain = EINA_FALSE;
14790    Eina_Bool text = EINA_FALSE;
14791    Eina_Bool font = EINA_FALSE;
14792    Eina_Bool repch = EINA_FALSE;
14793    Eina_Bool size = EINA_FALSE;
14794    Eina_Bool text_class = EINA_FALSE;
14795    Eina_Bool size_range = EINA_FALSE;
14796    Eina_Bool fit = EINA_FALSE;
14797    Eina_Bool min = EINA_FALSE;
14798    Eina_Bool max = EINA_FALSE;
14799    Eina_Bool align = EINA_FALSE;
14800    Eina_Bool source = EINA_FALSE;
14801    Eina_Bool text_source = EINA_FALSE;
14802    Eina_Bool ellipsis = EINA_FALSE;
14803    Eina_Bool style = EINA_FALSE;
14804 
14805    Edje_Part_Description_Text *txt = (Edje_Part_Description_Text *)pd;
14806    Edje_Part_Description_Text *inherit_pd_txt = (Edje_Part_Description_Text *)inherit_pd;
14807 
14808    if (inherit_pd_txt)
14809      {
14810         text = ((edje_string_id_get(&txt->text.text) ==
14811                  (edje_string_id_get(&inherit_pd_txt->text.text)))) ? EINA_FALSE : EINA_TRUE;
14812 
14813         font = ((edje_string_id_get(&inherit_pd_txt->text.font) ==
14814                  (edje_string_id_get(&txt->text.font)))) ? EINA_FALSE : EINA_TRUE;
14815 
14816         repch = ((edje_string_id_get(&inherit_pd_txt->text.repch) ==
14817                   (edje_string_id_get(&txt->text.repch)))) ? EINA_FALSE : EINA_TRUE;
14818 
14819         size = (inherit_pd_txt->text.size == txt->text.size) ? EINA_FALSE : EINA_TRUE;
14820 
14821         text_class = ((inherit_pd_txt->text.text_class == txt->text.text_class) ||
14822                       ((inherit_pd_txt->text.text_class != NULL) &&
14823                       (txt->text.text_class != NULL) &&
14824                       (!strcmp(inherit_pd_txt->text.text_class, txt->text.text_class)))) ? EINA_FALSE : EINA_TRUE;
14825 
14826         domain = ((inherit_pd_txt->text.domain == txt->text.domain) ||
14827                       ((inherit_pd_txt->text.domain != NULL) &&
14828                       (txt->text.domain != NULL) &&
14829                       (!strcmp(inherit_pd_txt->text.domain, txt->text.domain)))) ? EINA_FALSE : EINA_TRUE;
14830 
14831         size_range = ((inherit_pd_txt->text.size_range_max == txt->text.size_range_max) &&
14832                       (inherit_pd_txt->text.size_range_min == txt->text.size_range_min)) ? EINA_FALSE : EINA_TRUE;
14833 
14834         fit = ((inherit_pd_txt->text.fit_x == txt->text.fit_x) &&
14835                (inherit_pd_txt->text.fit_y == txt->text.fit_y)) ? EINA_FALSE : EINA_TRUE;
14836 
14837         min = ((inherit_pd_txt->text.min_x == txt->text.min_x) &&
14838                (inherit_pd_txt->text.min_y == txt->text.min_y)) ? EINA_FALSE : EINA_TRUE;
14839 
14840         max = ((inherit_pd_txt->text.max_x == txt->text.max_x) &&
14841                (inherit_pd_txt->text.max_y == txt->text.max_y)) ? EINA_FALSE : EINA_TRUE;
14842 
14843         align = (EQ(inherit_pd_txt->text.align.x, txt->text.align.x) &&
14844                  EQ(inherit_pd_txt->text.align.y, txt->text.align.y)) ? EINA_FALSE : EINA_TRUE;
14845 
14846         source = ((inherit_pd_txt->text.id_source == txt->text.id_source)) ? EINA_FALSE : EINA_TRUE;
14847 
14848         text_source = ((inherit_pd_txt->text.id_text_source == txt->text.id_text_source)) ? EINA_FALSE : EINA_TRUE;
14849 
14850 
14851         ellipsis = (EQ(inherit_pd_txt->text.ellipsis, txt->text.ellipsis)) ? EINA_FALSE : EINA_TRUE;
14852 
14853         style = (edje_string_id_get(&inherit_pd_txt->text.style) ==
14854                  edje_string_id_get(&txt->text.style)) ? EINA_FALSE : EINA_TRUE;
14855 
14856         color_3 = ((inherit_pd_txt->text.color3.r == txt->text.color3.r) &&
14857                    (inherit_pd_txt->text.color3.g == txt->text.color3.g) &&
14858                    (inherit_pd_txt->text.color3.b == txt->text.color3.b) &&
14859                    (inherit_pd_txt->text.color3.a == txt->text.color3.a)) ? EINA_FALSE : EINA_TRUE;
14860 
14861      }
14862    else
14863      {
14864         text = (edje_string_get(&txt->text.text) == NULL) ? EINA_FALSE : EINA_TRUE;
14865         font = (edje_string_get(&txt->text.font) == NULL) ? EINA_FALSE : EINA_TRUE;
14866         repch = (edje_string_get(&txt->text.repch) == NULL) ? EINA_FALSE : EINA_TRUE;
14867         size = (txt->text.size == 0) ? EINA_FALSE : EINA_TRUE;
14868         text_class = (txt->text.text_class == NULL) ? EINA_FALSE : EINA_TRUE;
14869         domain = (txt->text.domain == NULL) ? EINA_FALSE : EINA_TRUE;
14870         size_range = ((txt->text.size_range_min == 0) && (txt->text.size_range_max == 0)) ? EINA_FALSE : EINA_TRUE;
14871         fit = ((txt->text.fit_x == 0) && (txt->text.fit_y == 0)) ? EINA_FALSE : EINA_TRUE;
14872         min = ((txt->text.min_x == 0) && (txt->text.min_y == 0)) ? EINA_FALSE : EINA_TRUE;
14873         max = ((txt->text.max_x == 0) && (txt->text.max_y == 0)) ? EINA_FALSE : EINA_TRUE;
14874         align = (EQ(txt->text.align.x, FROM_DOUBLE(0.5)) && EQ(txt->text.align.y, FROM_DOUBLE(0.5))) ? EINA_FALSE : EINA_TRUE;
14875         source = (txt->text.id_source == -1) ? EINA_FALSE : EINA_TRUE;
14876         text_source = (txt->text.id_text_source == -1) ? EINA_FALSE : EINA_TRUE;
14877         ellipsis = EQ(txt->text.ellipsis, ZERO) ? EINA_FALSE : EINA_TRUE;
14878         style = (edje_string_id_get(&txt->text.style) == 0) ? EINA_FALSE : EINA_TRUE;
14879         color_3 = ((txt->text.color3.r == 0) && (txt->text.color3.g == 0) &&
14880                    (txt->text.color3.b == 0) && (txt->text.color3.a == 128)) ? EINA_FALSE : EINA_TRUE;
14881      }
14882 
14883    if (color_3)
14884      BUF_APPENDF(I5 "color3: %d %d %d %d;\n",
14885                       txt->text.color3.r, txt->text.color3.g, txt->text.color3.b, txt->text.color3.a);
14886 
14887 
14888    attr_amount = text + font + repch + size + text_class + domain +
14889                  size_range + fit + min + max + align + source + text_source + ellipsis + style;
14890 
14891    if (attr_amount == 0) return;
14892 
14893    if (attr_amount > 1)
14894      indent_space = strlen(I6);
14895 
14896    if (attr_amount > 1)
14897      BUF_APPEND(I5 "text {\n");
14898    else
14899      BUF_APPEND(I5 "text.");
14900 
14901    if (text)
14902      {
14903         if (txt->text.text.id)
14904           BUF_APPENDF("%*stext: _(\"%s\");\n", indent_space, "", edje_string_id_get(&txt->text.text));
14905         else if (edje_string_get(&txt->text.text) == NULL)
14906           BUF_APPENDF("%*stext: \"\";\n", indent_space, "");
14907         else
14908           BUF_APPENDF("%*stext: \"%s\";\n", indent_space, "", edje_string_get(&txt->text.text));
14909      }
14910 
14911    if (font)
14912      {
14913         if (txt->text.font.id)
14914           BUF_APPENDF("%*sfont: _(\"%s\");\n", indent_space, "", edje_string_id_get(&txt->text.font));
14915         else if (edje_string_get(&txt->text.font) == NULL)
14916           BUF_APPENDF("%*sfont: \"\";\n", indent_space, "");
14917         else
14918           BUF_APPENDF("%*sfont: \"%s\";\n", indent_space, "", edje_string_get(&txt->text.font));
14919      }
14920 
14921    if (repch)
14922      BUF_APPENDF("%*srepch: \"%s\";\n", indent_space, "", edje_string_id_get(&txt->text.repch));
14923 
14924    if (size)
14925      BUF_APPENDF("%*ssize: %d;\n", indent_space, "", txt->text.size);
14926 
14927    if (text_class)
14928      BUF_APPENDF("%*stext_class: \"%s\";\n", indent_space, "", txt->text.text_class);
14929 
14930    if (domain)
14931      BUF_APPENDF("%*sdomain: \"%s\";\n", indent_space, "", txt->text.domain);
14932 
14933    if (size_range)
14934      BUF_APPENDF("%*ssize_range: %d %d;\n", indent_space, "", txt->text.size_range_min, txt->text.size_range_max);
14935 
14936    if (fit)
14937      BUF_APPENDF("%*sfit: %d %d;\n", indent_space, "", txt->text.fit_x, txt->text.fit_y);
14938 
14939    if (min)
14940      BUF_APPENDF("%*smin: %d %d;\n", indent_space, "", txt->text.min_x, txt->text.min_y);
14941 
14942    if (max)
14943      BUF_APPENDF("%*smax: %d %d;\n", indent_space, "", txt->text.max_x, txt->text.max_y);
14944 
14945    if (align)
14946      {
14947         char align_str[strlen("align") + indent_space + 1];
14948         snprintf(align_str, strlen("align") + indent_space + 1,
14949                  "%*salign", indent_space, "");
14950         _edje_source_with_double_values_append(align_str, 2,
14951                                             TO_DOUBLE(txt->text.align.x),
14952                                             TO_DOUBLE(txt->text.align.y),
14953                                             buf, &ret);
14954      }
14955 
14956    if (source)
14957      BUF_APPENDF("%*ssource: \"%s\";\n", indent_space, "", _edje_part_name_find(ed, txt->text.id_source));
14958 
14959    if (text_source)
14960      BUF_APPENDF("%*stext_source: \"%s\";\n", indent_space, "", _edje_part_name_find(ed, txt->text.id_text_source));
14961 
14962    if (ellipsis)
14963      {
14964         char ellipsis_str[strlen("ellipsis") + indent_space + 1];
14965         snprintf(ellipsis_str, strlen("ellipsis") + indent_space + 1,
14966                  "%*sellipsis", indent_space, "");
14967          _edje_source_with_double_values_append(ellipsis_str, 1,
14968                                                txt->text.ellipsis,
14969                                                0.0, buf, &ret);
14970      }
14971    if (style)
14972      BUF_APPENDF("%*sstyle: \"%s\";\n", indent_space, "", edje_string_id_get(&txt->text.style));
14973 
14974    //TODO Filter
14975    if (attr_amount > 1)
14976      BUF_APPEND(I5 "}\n");
14977 }
14978 
14979 #define COMMON_STATE_ATTRIBUTES_AMOUNT 32
14980 static int
_edje_common_desc_diff_calculate(Edje_Part_Description_Common * ed,Edje_Part_Description_Common * inherit_pd)14981 _edje_common_desc_diff_calculate(Edje_Part_Description_Common *ed,
14982                                  Edje_Part_Description_Common *inherit_pd)
14983 {
14984    int diffs_amount= 0;
14985 
14986    diffs_amount += (NEQ(ed->align.x, inherit_pd->align.x) || NEQ(ed->align.y, inherit_pd->align.y)) ? 1 : 0;
14987 
14988    diffs_amount += ((ed->minmul.have != inherit_pd->minmul.have) ||
14989                     NEQ(ed->minmul.w, inherit_pd->minmul.w) ||
14990                     NEQ(ed->minmul.h, inherit_pd->minmul.h)) ? 1 : 0;
14991    diffs_amount += ((ed->min.w != inherit_pd->min.w) ||
14992                     (ed->min.h != inherit_pd->min.h) ||
14993                     (ed->min.limit != inherit_pd->min.limit)) ? 1 : 0;
14994    diffs_amount += ((ed->step.x != inherit_pd->step.x) || (ed->step.y != inherit_pd->step.y)) ? 1 : 0;
14995    diffs_amount += (NEQ(ed->aspect.min, inherit_pd->aspect.min) ||
14996                     NEQ(ed->aspect.max, inherit_pd->aspect.max) ||
14997                     (ed->aspect.prefer!= inherit_pd->aspect.prefer)) ? 1 : 0;
14998    diffs_amount += ((ed->color_class != NULL && inherit_pd->color_class == NULL) ||
14999                     (ed->color_class == NULL && inherit_pd->color_class != NULL) ||
15000                     (ed->color_class != NULL && inherit_pd->color_class != NULL &&
15001                      strcmp(ed->color_class, inherit_pd->color_class))) ? 1 : 0;
15002    diffs_amount += (ed->clip_to_id != inherit_pd->clip_to_id) ? 1 : 0;
15003    diffs_amount += ((ed->size_class != NULL && inherit_pd->size_class == NULL) ||
15004                     (ed->size_class == NULL && inherit_pd->size_class != NULL) ||
15005                     (ed->size_class != NULL && inherit_pd->size_class != NULL &&
15006                      strcmp(ed->size_class, inherit_pd->size_class))) ? 1 : 0;
15007 
15008    /*Rel1 block*/
15009    diffs_amount += (NEQ(ed->rel1.relative_x, inherit_pd->rel1.relative_x) ||
15010                     NEQ(ed->rel1.relative_y, inherit_pd->rel1.relative_y)) ? 1 : 0;
15011    diffs_amount += ((ed->rel1.offset_x != inherit_pd->rel1.offset_x) ||
15012                     (ed->rel1.offset_y != inherit_pd->rel1.offset_y)) ? 1 : 0;
15013    diffs_amount += (ed->rel1.id_x != inherit_pd->rel1.id_x) ? 1 : 0;
15014    diffs_amount += (ed->rel1.id_y != inherit_pd->rel1.id_y) ? 1 : 0;
15015    /*End of Rel1 block*/
15016 
15017    /*Rel2 block*/
15018    diffs_amount += (NEQ(ed->rel2.relative_x, inherit_pd->rel2.relative_x) ||
15019                     NEQ(ed->rel2.relative_y, inherit_pd->rel2.relative_y)) ? 1 : 0;
15020    diffs_amount += ((ed->rel2.offset_x != inherit_pd->rel2.offset_x) ||
15021                     (ed->rel2.offset_y != inherit_pd->rel2.offset_y)) ? 1 : 0;
15022    diffs_amount += (ed->rel2.id_x != inherit_pd->rel2.id_x) ? 1 : 0;
15023    diffs_amount += (ed->rel2.id_y != inherit_pd->rel2.id_y) ? 1 : 0;
15024    /*End of Rel1 block*/
15025 
15026    diffs_amount += (ed->visible != inherit_pd->visible) ? 1 : 0;
15027 
15028    diffs_amount += (inherit_pd->map.id_persp == ed->map.id_persp) ? EINA_FALSE : EINA_TRUE;
15029    diffs_amount += (inherit_pd->map.id_light == ed->map.id_light) ? EINA_FALSE : EINA_TRUE;
15030    diffs_amount += (inherit_pd->map.colors_count == ed->map.colors_count) ? EINA_FALSE : EINA_TRUE;
15031    diffs_amount += (inherit_pd->map.backcull == ed->map.backcull) ? EINA_FALSE : EINA_TRUE;
15032    diffs_amount += (inherit_pd->map.on == ed->map.on) ? EINA_FALSE : EINA_TRUE;
15033    diffs_amount += (inherit_pd->map.persp_on == ed->map.persp_on) ? EINA_FALSE : EINA_TRUE;
15034    diffs_amount += (inherit_pd->map.smooth == ed->map.smooth) ? EINA_FALSE : EINA_TRUE;
15035    diffs_amount += (inherit_pd->map.alpha == ed->map.alpha) ? EINA_FALSE : EINA_TRUE;
15036 
15037    diffs_amount += (inherit_pd->map.rot.id_center == ed->map.rot.id_center) ? EINA_FALSE : EINA_TRUE;
15038    diffs_amount += EQ(inherit_pd->map.rot.x, ed->map.rot.x) ? EINA_FALSE : EINA_TRUE;
15039    diffs_amount += EQ(inherit_pd->map.rot.y, ed->map.rot.y) ? EINA_FALSE : EINA_TRUE;
15040    diffs_amount += EQ(inherit_pd->map.rot.z, ed->map.rot.z) ? EINA_FALSE : EINA_TRUE;
15041 
15042    /*In case when colors are equal do not append points into diffs_amount*/
15043    diffs_amount += ((ed->color.r == inherit_pd->color.r) &&
15044                     (ed->color.g == inherit_pd->color.g) &&
15045                     (ed->color.b == inherit_pd->color.g) &&
15046                     (ed->color.a == inherit_pd->color.a)) ? EINA_FALSE : EINA_TRUE;
15047    diffs_amount += ((ed->color2.r == inherit_pd->color2.r) &&
15048                     (ed->color2.g == inherit_pd->color2.g) &&
15049                     (ed->color2.b == inherit_pd->color2.g) &&
15050                     (ed->color2.a == inherit_pd->color2.a)) ? EINA_FALSE : EINA_TRUE;
15051 
15052    return diffs_amount;
15053 }
15054 
15055 #define TEXT_STATE_ATTRIBUTES_AMOUNT (14 + COMMON_STATE_ATTRIBUTES_AMOUNT)
15056 static int
_edje_text_desc_diff_calculate(Edje_Part_Description_Common * ed,Edje_Part_Description_Common * inherit_pd)15057 _edje_text_desc_diff_calculate(Edje_Part_Description_Common *ed, Edje_Part_Description_Common *inherit_pd)
15058 {
15059    int diffs_amount=  _edje_common_desc_diff_calculate(ed, inherit_pd);
15060 
15061    Edje_Part_Description_Text *ed_text = (Edje_Part_Description_Text *) ed;
15062    Edje_Part_Description_Text *inherit_pd_text = (Edje_Part_Description_Text *) inherit_pd;
15063 
15064    diffs_amount += ((ed_text->text.color3.r == inherit_pd_text->text.color3.r) &&
15065                     (ed_text->text.color3.g == inherit_pd_text->text.color3.g) &&
15066                     (ed_text->text.color3.b == inherit_pd_text->text.color3.g) &&
15067                     (ed_text->text.color3.a == inherit_pd_text->text.color3.a)) ? EINA_FALSE : EINA_TRUE;
15068 
15069    /*Descriprion specific comparsion */
15070    diffs_amount += ((ed_text->text.text.str == NULL && inherit_pd_text->text.text.str != NULL) ||
15071                     (ed_text->text.text.str != NULL && inherit_pd_text->text.text.str == NULL) ||
15072                     (ed_text->text.text.str != NULL && inherit_pd_text->text.text.str != NULL &&
15073                      strcmp(ed_text->text.text.str, inherit_pd_text->text.text.str))) ? 1 : 0;
15074 
15075    diffs_amount += ((ed_text->text.domain != NULL && inherit_pd_text->text.domain == NULL) ||
15076                     (ed_text->text.domain == NULL && inherit_pd_text->text.domain != NULL) ||
15077                     (ed_text->text.domain != NULL && inherit_pd_text->text.domain != NULL &&
15078                      strcmp(ed_text->text.domain, inherit_pd_text->text.domain))) ? 1 : 0;
15079 
15080    diffs_amount += ((ed_text->text.text_class != NULL && inherit_pd_text->text.text_class == NULL) ||
15081                     (ed_text->text.text_class == NULL && inherit_pd_text->text.text_class != NULL) ||
15082                     (ed_text->text.text_class != NULL && inherit_pd_text->text.text_class != NULL &&
15083                      strcmp(ed_text->text.text_class, inherit_pd_text->text.text_class))) ? 1 : 0;
15084 
15085    diffs_amount += ((ed_text->text.font.str == NULL && inherit_pd_text->text.font.str != NULL) ||
15086                     (ed_text->text.font.str != NULL && inherit_pd_text->text.font.str == NULL) ||
15087                     (ed_text->text.font.str != NULL && inherit_pd_text->text.font.str != NULL &&
15088                      strcmp(ed_text->text.font.str, inherit_pd_text->text.font.str))) ? 1 : 0;
15089 
15090    diffs_amount += (NEQ(ed_text->text.align.x, inherit_pd_text->text.align.x) ||
15091                     NEQ(ed_text->text.align.y, inherit_pd_text->text.align.y)) ? 1 : 0;
15092    diffs_amount += NEQ(ed_text->text.ellipsis, inherit_pd_text->text.ellipsis) ? 1 : 0;
15093    diffs_amount += (ed_text->text.size != inherit_pd_text->text.size) ? 1 : 0;
15094    diffs_amount += (ed_text->text.id_source != inherit_pd_text->text.id_source) ? 1 : 0;
15095    diffs_amount += (ed_text->text.id_text_source != inherit_pd_text->text.id_text_source) ? 1 : 0;
15096    diffs_amount += ((ed_text->text.fit_x != inherit_pd_text->text.fit_x) ||
15097                     (ed_text->text.fit_y != inherit_pd_text->text.fit_y)) ? 1 : 0;
15098    diffs_amount += ((ed_text->text.min_x != inherit_pd_text->text.min_x) ||
15099                     (ed_text->text.min_y != inherit_pd_text->text.min_y)) ? 1 : 0;
15100    diffs_amount += ((ed_text->text.max_x != inherit_pd_text->text.max_x) ||
15101                     (ed_text->text.max_y != inherit_pd_text->text.max_y)) ? 1 : 0;
15102    diffs_amount += ((ed_text->text.size_range_min != inherit_pd_text->text.size_range_min) ||
15103                     (ed_text->text.size_range_max != inherit_pd_text->text.size_range_max)) ? 1 : 0;
15104 
15105    return diffs_amount;
15106 }
15107 
15108 #define IMAGE_STATE_ATTRIBUTES_AMOUNT (5 + COMMON_STATE_ATTRIBUTES_AMOUNT)
15109 static int
_edje_image_desc_diff_calculate(Edje_Edit * eed,Edje_Part_Description_Common * pd,Edje_Part_Description_Common * inherit_pd)15110 _edje_image_desc_diff_calculate(Edje_Edit *eed,
15111                                 Edje_Part_Description_Common *pd,
15112                                 Edje_Part_Description_Common *inherit_pd)
15113 {
15114    int diffs_amount = _edje_common_desc_diff_calculate(pd, inherit_pd);
15115 
15116    /*TODO: support tweens */
15117    Edje_Part_Description_Image *image_pd = (Edje_Part_Description_Image *) pd;
15118    Edje_Part_Description_Image *inherit_pd_image = (Edje_Part_Description_Image *) inherit_pd;
15119 
15120    const char *image_name = _edje_image_name_find(eed, image_pd->image.id);
15121    const char *inherit_name = _edje_image_name_find(eed, inherit_pd_image->image.id);
15122    diffs_amount += ((image_name != NULL) && (inherit_name != NULL) &&
15123                     (!strcmp(image_name, inherit_name))) ? EINA_FALSE : EINA_TRUE;
15124 
15125    diffs_amount += ((image_pd->image.border.l == inherit_pd_image->image.border.l) &&
15126              (image_pd->image.border.r == inherit_pd_image->image.border.r) &&
15127              (image_pd->image.border.t == inherit_pd_image->image.border.t) &&
15128              (image_pd->image.border.b == inherit_pd_image->image.border.b)) ? EINA_FALSE : EINA_TRUE;
15129 
15130    diffs_amount += (image_pd->image.border.scale == inherit_pd_image->image.border.scale) ? EINA_FALSE : EINA_TRUE;
15131 
15132    diffs_amount += EQ(image_pd->image.border.scale_by, inherit_pd_image->image.border.scale_by) ? EINA_FALSE : EINA_TRUE;
15133 
15134    diffs_amount += (image_pd->image.scale_hint == inherit_pd_image->image.scale_hint) ? EINA_FALSE : EINA_TRUE;
15135 
15136    diffs_amount += (image_pd->image.border.no_fill == inherit_pd_image->image.border.no_fill) ? EINA_FALSE : EINA_TRUE;
15137 
15138    return diffs_amount;
15139 }
15140 
15141 static Edje_Part_Description_Common *
_edje_generate_source_of_state_inherit(Edje_Edit * eed EINA_UNUSED,Edje_Part * ep,Edje_Part_Description_Common * pd)15142 _edje_generate_source_of_state_inherit(Edje_Edit *eed EINA_UNUSED, Edje_Part *ep, Edje_Part_Description_Common *pd)
15143 {
15144 /*
15145  * DIFFERENCE_LEVEL constant describe coefficient of difference.
15146  * All states pairs, that has the difference coefficient below
15147  * than this constant, could be inhereted one by one.
15148  * Value 10 mean that states should has maximum 10% differences in all attributes
15149  */
15150 
15151 #define DIFFERENCE_LEVEL 10
15152    unsigned int i = 0;
15153    int diff_min = 99;
15154    int diff_coeff = 99;
15155    int diff_amount = 0;
15156 
15157    Edje_Part_Description_Common *inherit = NULL;
15158    Edje_Part_Description_Common *desc = NULL;
15159 
15160    if (EQ(pd->state.value, ZERO) && !strcmp(pd->state.name, "default"))
15161      return NULL;
15162 
15163    /*calculate  metric of difference*/
15164    switch (ep->type)
15165      {
15166       /*TODO: add speceific part types description diff calculating*/
15167       case EDJE_PART_TYPE_TEXT:
15168          diff_amount = _edje_text_desc_diff_calculate(pd, ep->default_desc);
15169          diff_coeff = (int)(((100 * diff_amount) / (TEXT_STATE_ATTRIBUTES_AMOUNT)));
15170          break;
15171       case EDJE_PART_TYPE_IMAGE:
15172          diff_amount = _edje_image_desc_diff_calculate(eed, pd, ep->default_desc);
15173          diff_coeff = (int)(((100 * diff_amount) / (IMAGE_STATE_ATTRIBUTES_AMOUNT)));
15174          break;
15175       default:
15176          diff_amount = _edje_common_desc_diff_calculate(pd, ep->default_desc);
15177          diff_coeff = (int)(((100 * diff_amount) / (COMMON_STATE_ATTRIBUTES_AMOUNT)));
15178          break;
15179      }
15180 
15181   if ((diff_coeff <= DIFFERENCE_LEVEL) && (diff_coeff < diff_min))
15182      {
15183         diff_min = diff_coeff;
15184         inherit = ep->default_desc;
15185      }
15186 
15187    /*
15188     * For case when beetwen current state and "default" state little amount of
15189     * differencies - stop search
15190     */
15191    if (inherit && diff_amount <= 1)
15192      return inherit;
15193 
15194    for (i = 0; i < ep->other.desc_count; i++)
15195      {
15196         desc = ep->other.desc[i];
15197 
15198         if (!strcmp(desc->state.name, pd->state.name) && EQ(desc->state.value, pd->state.value))
15199           break;
15200 
15201         /*calculate  metric of difference*/
15202          switch (ep->type)
15203            {
15204             /*TODO: add speceific part types description diff calculating*/
15205             case EDJE_PART_TYPE_TEXT:
15206                diff_coeff = _edje_text_desc_diff_calculate(pd, desc);
15207                break;
15208             case EDJE_PART_TYPE_IMAGE:
15209                diff_coeff = _edje_image_desc_diff_calculate(eed, pd, desc);
15210                break;
15211             default:
15212                diff_coeff = _edje_common_desc_diff_calculate(pd, desc);
15213                break;
15214            }
15215          if ((diff_coeff <= DIFFERENCE_LEVEL) && (diff_coeff < diff_min))
15216            {
15217               diff_min = diff_coeff;
15218               inherit = desc;
15219            }
15220      }
15221    return inherit;
15222 }
15223 
15224 static Eina_Bool
_edje_generate_source_of_state(Evas_Object * obj,const char * part,const char * state,double value,Eina_Strbuf * buf)15225 _edje_generate_source_of_state(Evas_Object *obj, const char *part, const char *state, double value, Eina_Strbuf *buf)
15226 {
15227    Eina_List *l, *ll;
15228    Eina_Bool ret = EINA_TRUE;
15229 
15230    GET_PD_OR_RETURN(EINA_FALSE);
15231 
15232    BUF_APPENDF(I4 "description { state: \"%s\"", pd->state.name);
15233    _edje_source_with_double_values_append(NULL, 1, pd->state.value, 0, buf, &ret);
15234 
15235    Edje_Part_Description_Common *inherit_pd = _edje_generate_source_of_state_inherit(eed, rp->part, pd);
15236 
15237    Eina_Bool color = EINA_FALSE;
15238    Eina_Bool color_2 = EINA_FALSE;
15239    Eina_Bool color_class = EINA_FALSE;
15240    Eina_Bool align = EINA_FALSE;
15241    Eina_Bool fixed = EINA_FALSE;
15242    Eina_Bool size_class = EINA_FALSE;
15243    Eina_Bool minmul = EINA_FALSE;
15244    Eina_Bool min = EINA_FALSE, min_source = EINA_FALSE;
15245    Eina_Bool max = EINA_FALSE, max_source = EINA_FALSE;
15246    Eina_Bool aspect = EINA_FALSE;
15247    Eina_Bool aspect_prefer = EINA_FALSE;
15248    Eina_Bool step = EINA_FALSE;
15249    Eina_Bool limit = EINA_FALSE;
15250    Eina_Bool zplane = EINA_FALSE;
15251    Eina_Bool focal = EINA_FALSE;
15252    Eina_Bool clip_to = EINA_FALSE;
15253 
15254    if (inherit_pd)
15255      {
15256         BUF_APPENDF(I5 "inherit: \"%s\" %.2f;\n", inherit_pd->state.name, inherit_pd->state.value);
15257 
15258         color =  ((pd->color.r == inherit_pd->color.r) &&
15259                   (pd->color.g == inherit_pd->color.g) &&
15260                   (pd->color.b == inherit_pd->color.b) &&
15261                   (pd->color.a == inherit_pd->color.a)) ? EINA_FALSE : EINA_TRUE;
15262 
15263         color_2 =  ((pd->color2.r == inherit_pd->color2.r) &&
15264                     (pd->color2.g == inherit_pd->color2.g) &&
15265                     (pd->color2.b == inherit_pd->color2.b) &&
15266                     (pd->color2.a == inherit_pd->color2.a)) ? EINA_FALSE : EINA_TRUE;
15267 
15268         color_class = ((pd->color_class == inherit_pd->color_class) ||
15269                        ((pd->color_class != NULL) &&
15270                         (inherit_pd->color_class != NULL) &&
15271                         (!strcmp(pd->color_class, inherit_pd->color_class)))) ? EINA_FALSE : EINA_TRUE;
15272 
15273         align = (EQ(pd->align.x, inherit_pd->align.x) &&
15274                  EQ(pd->align.y, inherit_pd->align.y)) ? EINA_FALSE : EINA_TRUE;
15275 
15276         fixed = ((pd->fixed.w == inherit_pd->fixed.w) &&
15277                  (pd->fixed.h == inherit_pd->fixed.h)) ? EINA_FALSE : EINA_TRUE;
15278 
15279         min = ((pd->min.w == inherit_pd->min.w) &&
15280                (pd->min.h == inherit_pd->min.h)) ? EINA_FALSE : EINA_TRUE;
15281 
15282         min_source = (pd->min.limit == inherit_pd->min.limit) ? EINA_FALSE : EINA_TRUE;
15283 
15284         max = ((pd->max.w == inherit_pd->max.w) &&
15285                (pd->max.h == inherit_pd->max.h)) ? EINA_FALSE : EINA_TRUE;
15286 
15287         max_source = (pd->max.limit == inherit_pd->max.limit) ? EINA_FALSE : EINA_TRUE;
15288 
15289         minmul = ((pd->minmul.have == inherit_pd->minmul.have) &&
15290                   EQ(pd->minmul.w, inherit_pd->minmul.w) &&
15291                   EQ(pd->minmul.h, inherit_pd->minmul.h)) ? EINA_FALSE : EINA_TRUE;
15292 
15293         size_class = ((pd->size_class == inherit_pd->size_class) ||
15294                       ((pd->size_class != NULL) && (inherit_pd->size_class != NULL) &&
15295                        (!strcmp(pd->size_class, inherit_pd->size_class)))) ? EINA_FALSE : EINA_TRUE;
15296 
15297         step = ((pd->step.x == inherit_pd->step.x) &&
15298                 (pd->step.y == inherit_pd->step.y)) ? EINA_FALSE : EINA_TRUE;
15299 
15300         aspect = (EQ(pd->aspect.min, inherit_pd->aspect.min) &&
15301                   EQ(pd->aspect.max, inherit_pd->aspect.max)) ? EINA_FALSE : EINA_TRUE;
15302 
15303         aspect_prefer = (pd->aspect.prefer == inherit_pd->aspect.prefer) ? EINA_FALSE : EINA_TRUE;
15304 
15305         limit = (pd->limit == inherit_pd->limit) ? EINA_FALSE : EINA_TRUE;
15306 
15307         zplane = (pd->persp.zplane == inherit_pd->persp.zplane) ? EINA_FALSE : EINA_TRUE;
15308 
15309         focal = (pd->persp.focal == inherit_pd->persp.focal) ? EINA_FALSE : EINA_TRUE;
15310 
15311         clip_to = (pd->clip_to_id == inherit_pd->clip_to_id) ? EINA_FALSE : EINA_TRUE;
15312      }
15313    else
15314      {
15315         color = ((pd->color.r == 255) && (pd->color.g == 255) &&
15316                  (pd->color.b == 255) && (pd->color.a == 255)) ? EINA_FALSE : EINA_TRUE;
15317 
15318         color_2 = ((pd->color2.r == 0) && (pd->color2.g == 0) &&
15319                    (pd->color2.b == 0) && (pd->color2.a == 255)) ? EINA_FALSE : EINA_TRUE;
15320 
15321         color_class = (pd->color_class == NULL) ? EINA_FALSE : EINA_TRUE;
15322 
15323         align = (EQ(pd->align.x, FROM_DOUBLE(0.5)) && EQ(pd->align.y, FROM_DOUBLE(0.5))) ? EINA_FALSE : EINA_TRUE;
15324 
15325         fixed = ((pd->fixed.w == 0) && (pd->fixed.h == 0)) ? EINA_FALSE : EINA_TRUE;
15326 
15327         min = ((pd->min.w == 0) && (pd->min.h == 0)) ? EINA_FALSE : EINA_TRUE;
15328         min_source = pd->min.limit;
15329 
15330         max = ((pd->max.w == -1) && (pd->max.h == -1)) ? EINA_FALSE : EINA_TRUE;
15331         max_source = pd->max.limit;
15332 
15333         minmul = ((pd->minmul.have == 0) ||
15334                   (EQ(pd->minmul.w, FROM_INT(1)) && EQ(pd->minmul.h, FROM_INT(1)))) ? EINA_FALSE : EINA_TRUE;
15335 
15336         size_class = (pd->size_class == NULL) ? EINA_FALSE : EINA_TRUE;
15337 
15338         step = ((pd->step.x == 0) && (pd->step.y == 0)) ? EINA_FALSE : EINA_TRUE;
15339 
15340         aspect = (EQ(pd->aspect.min, ZERO) && EQ(pd->aspect.max, ZERO)) ? EINA_FALSE : EINA_TRUE;
15341 
15342         aspect_prefer = (pd->aspect.prefer == 0) ? EINA_FALSE : EINA_TRUE;
15343 
15344         limit = (pd->limit == EDJE_STATE_LIMIT_NONE) ? EINA_FALSE : EINA_TRUE;
15345 
15346         zplane = (pd->persp.zplane == 0) ? EINA_FALSE : EINA_TRUE;
15347 
15348         focal = (pd->persp.focal == 1000) ? EINA_FALSE : EINA_TRUE;
15349 
15350         clip_to = (pd->clip_to_id == -1) ? EINA_FALSE : EINA_TRUE;
15351      }
15352 
15353    if (inherit_pd && inherit_pd->visible != pd->visible)
15354      {
15355        BUF_APPENDF(I5 "visible: %d;\n", pd->visible);
15356      }
15357    else if (!pd->visible)
15358      {
15359        BUF_APPEND(I5 "visible: 0;\n");
15360      }
15361 
15362    if (limit)
15363      {
15364         switch (pd->limit)
15365           {
15366            case EDJE_STATE_LIMIT_WIDTH:
15367            {
15368               BUF_APPEND(I5 "limit: WIDTH;\n");
15369               break;
15370            }
15371 
15372            case EDJE_STATE_LIMIT_HEIGHT:
15373            {
15374               BUF_APPEND(I5 "limit: HEIGHT;\n");
15375               break;
15376            }
15377 
15378            case EDJE_STATE_LIMIT_BOTH:
15379            {
15380               BUF_APPEND(I5 "limit: BOTH;\n");
15381               break;
15382            }
15383           }
15384      }
15385 
15386    if (align)
15387      _edje_source_with_double_values_append(I5 "align", 2,
15388                                             TO_DOUBLE(pd->align.x),
15389                                             TO_DOUBLE(pd->align.y),
15390                                             buf, &ret);
15391 
15392    if (fixed)
15393      BUF_APPENDF(I5 "fixed: %d %d;\n", pd->fixed.w, pd->fixed.h);
15394 
15395    if (min && !min_source)
15396      BUF_APPENDF(I5 "min: %d %d;\n", pd->min.w, pd->min.h);
15397    else if (min_source)
15398      BUF_APPEND(I5 "min: SOURCE;\n");
15399 
15400    if (max && !max_source)
15401      BUF_APPENDF(I5 "max: %d %d;\n", pd->max.w, pd->max.h);
15402    else if (max_source)
15403      BUF_APPEND(I5 "max: SOURCE;\n");
15404 
15405    if (minmul)
15406      _edje_source_with_double_values_append(I5 "minmul", 2,
15407                                             TO_DOUBLE(pd->minmul.w),
15408                                             TO_DOUBLE(pd->minmul.h),
15409                                             buf, &ret);
15410 
15411    if (size_class)
15412      BUF_APPENDF(I5 "size_class: \"%s\";\n", pd->size_class);
15413 
15414    if (step)
15415      BUF_APPENDF(I5 "step: %d %d;\n", TO_INT(pd->step.x), TO_INT(pd->step.y));
15416 
15417    if (aspect)
15418      _edje_source_with_double_values_append(I5 "aspect", 2,
15419                                             TO_DOUBLE(pd->aspect.min),
15420                                             TO_DOUBLE(pd->aspect.max),
15421                                             buf, &ret);
15422 
15423    if (aspect_prefer)
15424      BUF_APPENDF(I5 "aspect_preference: %s;\n", prefers[(int)pd->aspect.prefer]);
15425 
15426    if (clip_to)
15427      BUF_APPENDF(I5 "clip_to: \"%s\";\n",
15428                       (pd->clip_to_id == -1 ? "" : _edje_part_name_find(ed, pd->clip_to_id)));
15429 
15430 
15431    if (rp->part->type != EDJE_PART_TYPE_SPACER)
15432      {
15433         if (color_class)
15434           BUF_APPENDF(I5 "color_class: \"%s\";\n",
15435                       (pd->color_class == NULL ? "" : pd->color_class));
15436 
15437         if (color)
15438           BUF_APPENDF(I5 "color: %d %d %d %d;\n",
15439                       pd->color.r, pd->color.g, pd->color.b, pd->color.a);
15440         if (color_2)
15441           BUF_APPENDF(I5 "color2: %d %d %d %d;\n",
15442                       pd->color2.r, pd->color2.g, pd->color2.b, pd->color2.a);
15443      }
15444 
15445    //Box
15446    if (rp->part->type == EDJE_PART_TYPE_BOX)
15447      _edje_generate_source_state_box(pd, inherit_pd, buf);
15448 
15449    //Table
15450    if (rp->part->type == EDJE_PART_TYPE_TABLE)
15451      _edje_generate_source_state_table(pd, inherit_pd, buf);
15452 
15453    //Image
15454    if (rp->part->type == EDJE_PART_TYPE_IMAGE)
15455      _edje_generate_source_state_image(eed, obj, part, state, value, pd, inherit_pd, buf) ;
15456 
15457    //Proxy
15458    if (rp->part->type == EDJE_PART_TYPE_PROXY)
15459      _edje_generate_source_state_proxy(ed, pd, inherit_pd, buf);
15460 
15461    //Text
15462    if ((rp->part->type == EDJE_PART_TYPE_TEXT) ||
15463        (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK))
15464      _edje_generate_source_state_text(ed, pd, inherit_pd, buf);
15465 
15466    //External
15467    if (rp->part->type == EDJE_PART_TYPE_EXTERNAL)
15468      {
15469         if ((ll = (Eina_List *)edje_edit_state_external_params_list_get(obj, part, state, value)))
15470           {
15471              Edje_External_Param *p;
15472 
15473              BUF_APPEND(I5 "params {\n");
15474              EINA_LIST_FOREACH(ll, l, p)
15475                {
15476                   switch (p->type)
15477                     {
15478                      case EDJE_EXTERNAL_PARAM_TYPE_INT:
15479                        BUF_APPENDF(I6 "int: \"%s\" \"%d\";\n", p->name, p->i);
15480                        break;
15481 
15482                      case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
15483                        BUF_APPENDF(I6 "double: \"%s\" \"%g\";\n", p->name, p->d);
15484                        break;
15485 
15486                      case EDJE_EXTERNAL_PARAM_TYPE_STRING:
15487                        if (p->s)
15488                          BUF_APPENDF(I6 "string: \"%s\" \"%s\";\n", p->name,
15489                                      p->s);
15490                        break;
15491 
15492                      case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
15493                        BUF_APPENDF(I6 "bool: \"%s\" \"%d\";\n", p->name, p->i);
15494                        break;
15495 
15496                      case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
15497                        if (p->s)
15498                          BUF_APPENDF(I6 "choice: \"%s\" \"%s\";\n", p->name,
15499                                      p->s);
15500                        break;
15501 
15502                      default:
15503                        break;
15504                     }
15505                }
15506              BUF_APPEND(I5 "}\n");
15507           }
15508      }
15509 
15510    //Relative block
15511    _edje_generate_source_state_relative(ed, pd, inherit_pd, buf);
15512 
15513    //Map
15514    _edje_generate_source_state_map(ed, pd, inherit_pd, buf);
15515 
15516    if (zplane || focal)
15517      {
15518         if (zplane && focal)
15519           {
15520              BUF_APPEND(I5 "perspective {\n");
15521              BUF_APPENDF(I6 "zplane: %d;\n", pd->persp.zplane);
15522              BUF_APPENDF(I6 "focal: %d;\n", pd->persp.focal);
15523              BUF_APPEND(I5 "}\n");
15524           }
15525         else
15526           {
15527              BUF_APPEND(I5 "perspective.");
15528              if (zplane)
15529                BUF_APPENDF("zplane: %d;\n", pd->persp.zplane);
15530              if (focal)
15531                BUF_APPENDF("focal: %d;\n", pd->persp.focal);
15532           }
15533      }
15534 
15535    BUF_APPEND(I4 "}\n"); //description
15536    return ret;
15537 }
15538 
15539 static Eina_Bool
_edje_generate_source_of_part(Evas_Object * obj,Edje_Part * ep,Eina_Strbuf * buf)15540 _edje_generate_source_of_part(Evas_Object *obj, Edje_Part *ep, Eina_Strbuf *buf)
15541 {
15542    const char *part = ep->name;
15543    const char *str;
15544    Eina_List *l, *ll;
15545    char *data;
15546    Eina_Bool ret = EINA_TRUE;
15547    const char *api_name, *api_description;
15548    Edje_Pack_Element *item;
15549 
15550    GET_RP_OR_RETURN(EINA_FALSE);
15551 
15552    BUF_APPENDF(I3 "part { name: \"%s\";\n", part);
15553    BUF_APPENDF(I4 "type: %s;\n", types[rp->part->type]);
15554    if (!rp->part->mouse_events)
15555      BUF_APPEND(I4 "mouse_events: 0;\n");
15556    if (rp->part->repeat_events)
15557      BUF_APPEND(I4 "repeat_events: 1;\n");
15558    if (rp->part->scale)
15559      BUF_APPEND(I4 "scale: 1;\n");
15560 
15561    if (rp->part->ignore_flags)
15562      BUF_APPENDF(I4 "ignore_flags: \"ON_HOLD\";\n");
15563    if (rp->part->mask_flags)
15564      BUF_APPENDF(I4 "mask_flags: \"ON_HOLD\";\n");
15565    if (rp->part->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB)
15566      BUF_APPEND(I4 "pointer_mode: NOGRAB;\n");
15567    if (rp->part->precise_is_inside)
15568      BUF_APPEND(I4 "precise_is_inside: 1;\n");
15569    if (rp->part->access)
15570      BUF_APPEND(I4 "access: 1;\n");
15571    if (rp->part->allowed_seats)
15572      {
15573         Edje_Part_Allowed_Seat *seat;
15574         unsigned int i;
15575 
15576         BUF_APPEND(I4 "allowed_seats:");
15577         for (i = 0; i < rp->part->allowed_seats_count; i++)
15578           {
15579              seat = rp->part->allowed_seats[i];
15580              BUF_APPENDF(" %s", seat->name);
15581           }
15582         BUF_APPEND(";\n");
15583      }
15584 
15585    if ((str = _edje_part_clip_to_get(ed, rp)))
15586      {
15587         BUF_APPENDF(I4 "clip_to: \"%s\";\n", str);
15588         edje_edit_string_free(str);
15589      }
15590    if ((rp->part->type == EDJE_PART_TYPE_TEXTBLOCK) ||
15591        (rp->part->type == EDJE_PART_TYPE_TEXT))
15592      if (rp->part->use_alternate_font_metrics)
15593        BUF_APPENDF(I4 "use_alternate_font_metrics: 1;\n");
15594 
15595    if ((rp->part->type == EDJE_PART_TYPE_TEXTBLOCK) ||
15596        (rp->part->type == EDJE_PART_TYPE_GROUP))
15597      {
15598         if ((str = eina_stringshare_add(rp->part->source)))
15599           {
15600              BUF_APPENDF(I4 "source: \"%s\";\n", str);
15601              eina_stringshare_del(str);
15602           }
15603         if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
15604           {
15605              if ((str = eina_stringshare_add(rp->part->source2)))
15606                {
15607                   BUF_APPENDF(I4 "source2: \"%s\";\n", str);
15608                   eina_stringshare_del(str);
15609                }
15610              if ((str = eina_stringshare_add(rp->part->source3)))
15611                {
15612                   BUF_APPENDF(I4 "source3: \"%s\";\n", str);
15613                   eina_stringshare_del(str);
15614                }
15615              if ((str = eina_stringshare_add(rp->part->source4)))
15616                {
15617                   BUF_APPENDF(I4 "source4: \"%s\";\n", str);
15618                   eina_stringshare_del(str);
15619                }
15620              if ((str = eina_stringshare_add(rp->part->source5)))
15621                {
15622                   BUF_APPENDF(I4 "source5: \"%s\";\n", str);
15623                   eina_stringshare_del(str);
15624                }
15625              if ((str = eina_stringshare_add(rp->part->source6)))
15626                {
15627                   BUF_APPENDF(I4 "source6: \"%s\";\n", str);
15628                   eina_stringshare_del(str);
15629                }
15630              if (rp->part->entry_mode)
15631                BUF_APPENDF(I4 "entry_mode: \"%s\";\n",
15632                            entry_mode[rp->part->entry_mode]);
15633              if (rp->part->select_mode)
15634                BUF_APPENDF(I4 "select_mode: \"EXPLICIT\";\n");
15635              if (rp->part->cursor_mode)
15636                BUF_APPENDF(I4 "cursor_mode: \"BEFORE\";\n");
15637              if (rp->part->multiline)
15638                BUF_APPEND(I4 "multiline: 1;\n");
15639           }
15640      }
15641 
15642    if (rp->part->effect)
15643      {
15644         int effect = rp->part->effect;
15645         if (effect & EDJE_TEXT_EFFECT_MASK_SHADOW_DIRECTION)
15646           {
15647              BUF_APPENDF(I4 "effect: %s %s;\n",
15648                          effects[effect & ~EDJE_TEXT_EFFECT_MASK_SHADOW_DIRECTION],
15649                          shadow_direction[effect >> 4]);
15650           }
15651         else
15652           BUF_APPENDF(I4 "effect: %s;\n",
15653                       effects[effect]);
15654      }
15655 
15656    //Box
15657    if ((edje_edit_part_type_get(obj, part) == EDJE_PART_TYPE_BOX) ||
15658        (edje_edit_part_type_get(obj, part) == EDJE_PART_TYPE_TABLE))
15659      {
15660         if (ep->items_count != 0)
15661           {
15662              unsigned int i;
15663 
15664              if (edje_edit_part_type_get(obj, part) == EDJE_PART_TYPE_BOX)
15665                BUF_APPEND(I4 "box {\n");
15666              else
15667                BUF_APPEND(I4 "table {\n");
15668              BUF_APPEND(I5 "items {\n");
15669              for (i = 0; i < ep->items_count; ++i)
15670                {
15671                   item = ep->items[i];
15672                   BUF_APPEND(I6 "item {\n");
15673                   BUF_APPENDF(I7 "type: %s;\n", types[item->type]);
15674                   if (item->name)
15675                     BUF_APPENDF(I7 "name: \"%s\";\n", item->name);
15676                   if (item->source)
15677                     BUF_APPENDF(I7 "source: \"%s\";\n", item->source);
15678                   if ((item->min.w != 0) || (item->min.h != 0))
15679                     BUF_APPENDF(I7 "min: %d %d;\n", item->min.w, item->min.h);
15680                   if ((item->max.w != -1) || (item->max.h != -1))
15681                     BUF_APPENDF(I7 "max: %d %d;\n", item->max.w, item->max.h);
15682                   if (item->aspect.mode)
15683                     BUF_APPENDF(I7 "aspect_mode: \"%s\";\n", aspect_mode[item->aspect.mode]);
15684                   if ((item->aspect.w != 0) || (item->aspect.h != 0))
15685                     BUF_APPENDF(I7 "aspect: %d %d;\n", item->aspect.w, item->aspect.h);
15686                   if ((item->prefer.w != 0) || (item->prefer.h != 0))
15687                     BUF_APPENDF(I7 "prefer: %d %d;\n", item->prefer.w, item->prefer.h);
15688                   if ((item->spread.w != 1) || (item->spread.h != 1))
15689                     BUF_APPENDF(I7 "spread: %d %d;\n", item->spread.w, item->spread.h);
15690                   if ((item->padding.l != 0) || (item->padding.t != 0) ||
15691                       (item->padding.r != 0) || (item->padding.b != 0))
15692                     BUF_APPENDF(I7 "padding: %d %d %d %d;\n",
15693                                 item->padding.l, item->padding.r,
15694                                 item->padding.t, item->padding.b);
15695                   if (NEQ(item->weight.x, ZERO) || NEQ(item->weight.y, ZERO))
15696                     _edje_source_with_double_values_append(I7 "weight", 2,
15697                                                            TO_DOUBLE(item->weight.x),
15698                                                            TO_DOUBLE(item->weight.y),
15699                                                            buf, &ret);
15700                   if (NEQ(item->align.x, FROM_DOUBLE(0.5)) || NEQ(item->align.y, FROM_DOUBLE(0.5)))
15701                     _edje_source_with_double_values_append(I7 "align", 2,
15702                                                            TO_DOUBLE(item->align.x),
15703                                                            TO_DOUBLE(item->align.y),
15704                                                            buf, &ret);
15705 
15706                   if (edje_edit_part_type_get(obj, part) == EDJE_PART_TYPE_TABLE)
15707                     BUF_APPENDF(I7 "position: %d %d;\n", item->col, item->row);
15708                   if ((item->colspan != 1) || (item->rowspan != 1))
15709                     BUF_APPENDF(I7 "span: %d %d;\n", item->colspan, item->rowspan);
15710 
15711                   //TODO weight
15712                   //TODO options
15713                   //TODO col
15714                   //TODO row
15715 
15716                   BUF_APPEND(I6 "}\n");
15717                }
15718              BUF_APPEND(I5 "}\n");
15719              BUF_APPEND(I4 "}\n");
15720           }
15721      }
15722 
15723    //Dragable
15724    str = edje_edit_part_drag_event_get(obj, part);
15725    if (rp->part->dragable.x || rp->part->dragable.y || str)
15726      {
15727         BUF_APPEND(I4 "dragable {\n");
15728         if (str)
15729           {
15730              BUF_APPENDF(I5 "events: \"%s\";\n", str);
15731              edje_edit_string_free(str);
15732           }
15733 
15734         if (rp->part->dragable.x || rp->part->dragable.y)
15735           {
15736              BUF_APPENDF(I5 "x: %d %d %d;\n",
15737                          rp->part->dragable.x,
15738                          rp->part->dragable.step_x,
15739                          rp->part->dragable.count_x);
15740              BUF_APPENDF(I5 "y: %d %d %d;\n",
15741                          rp->part->dragable.y,
15742                          rp->part->dragable.step_y,
15743                          rp->part->dragable.count_y);
15744              if ((str = edje_edit_part_drag_confine_get(obj, part)))
15745                {
15746                   BUF_APPENDF(I5 "confine: \"%s\";\n", str);
15747                   edje_edit_string_free(str);
15748                }
15749              if ((str = edje_edit_part_drag_threshold_get(obj, part)))
15750                {
15751                   BUF_APPENDF(I5 "threshold: \"%s\";\n", str);
15752                   edje_edit_string_free(str);
15753                }
15754           }
15755         BUF_APPEND(I4 "}\n");
15756      }
15757 
15758    //Descriptions
15759    ll = edje_edit_part_states_list_get(obj, part);
15760    EINA_LIST_FOREACH(ll, l, data)
15761      {
15762         char state[512], *delim;
15763         double value;
15764         strncpy(state, data, sizeof(state) - 1); /* if we go over it, too bad.. the list of states may need to change to provide name and value separated */
15765         delim = strchr(state, ' ');
15766         if (!delim) continue;
15767         *delim = '\0';
15768         delim++;
15769         value = strtod(delim, NULL);
15770         ret &= _edje_generate_source_of_state(obj, part, state, value, buf);
15771      }
15772    edje_edit_string_list_free(ll);
15773 
15774    api_name = eina_stringshare_add(rp->part->api.name);
15775    api_description = eina_stringshare_add(rp->part->api.description);
15776    if (api_name || api_description)
15777      {
15778         if (api_name && api_description)
15779           {
15780              BUF_APPENDF(I4 "api: \"%s\" \"%s\";\n", api_name, api_description);
15781              eina_stringshare_del(api_name);
15782              eina_stringshare_del(api_description);
15783           }
15784         else
15785         if (api_name)
15786           {
15787              BUF_APPENDF(I4 "api: \"%s\" \"\";\n", api_name);
15788              eina_stringshare_del(api_name);
15789           }
15790         else
15791           {
15792              BUF_APPENDF(I4 "api: \"\" \"%s\";\n", api_description);
15793              eina_stringshare_del(api_description);
15794           }
15795      }
15796 
15797    BUF_APPEND(I3 "}\n"); //part
15798    return ret;
15799 }
15800 
15801 static void
_edje_generate_source_of_sounds(Edje_Sound_Directory * sound_directory,Eina_Strbuf * buf)15802 _edje_generate_source_of_sounds(Edje_Sound_Directory *sound_directory, Eina_Strbuf *buf)
15803 {
15804    unsigned int i = 0;
15805    Eina_Bool ret = EINA_TRUE;
15806    Edje_Sound_Sample *current_sample = sound_directory->samples;
15807    Edje_Sound_Tone *current_tone = sound_directory->tones;
15808    BUF_APPEND(I1 "sounds {\n");
15809 
15810    for (i = 0; i < sound_directory->samples_count; i++, current_sample++)
15811      {
15812         BUF_APPEND(I2 "sample {\n");
15813         BUF_APPENDF(I3 "name: \"%s\" ", current_sample->name);
15814         switch (current_sample->compression)
15815           {
15816            case EDJE_SOUND_SOURCE_TYPE_INLINE_RAW:
15817            {
15818               BUF_APPEND("RAW;\n");
15819               break;
15820            }
15821 
15822            case EDJE_SOUND_SOURCE_TYPE_INLINE_COMP:
15823            {
15824               BUF_APPEND("COMP;\n");
15825               break;
15826            }
15827 
15828            case EDJE_SOUND_SOURCE_TYPE_INLINE_LOSSY:
15829            {
15830               BUF_APPENDF("LOSSY %f;\n", current_sample->quality);
15831               break;
15832            }
15833 
15834            case EDJE_SOUND_SOURCE_TYPE_INLINE_AS_IS:
15835            {
15836               BUF_APPEND("AS_IS;\n");
15837               break;
15838            }
15839 
15840            default:
15841              break;
15842           }
15843         BUF_APPENDF(I3 "source: \"%s\";\n", current_sample->snd_src);
15844         BUF_APPEND(I2 "}\n");
15845      }
15846    for (i = 0; i < sound_directory->tones_count; i++, current_tone++)
15847      {
15848         BUF_APPEND(I2 "tone: ");
15849         BUF_APPENDF("\"%s\" %d;\n", current_tone->name, current_tone->value);
15850      }
15851 
15852    BUF_APPEND(I1 "}\n");
15853 }
15854 
15855 static void
_edje_limits_source_generate(const Edje * ed,Eina_Strbuf * buf,Eina_Bool * res)15856 _edje_limits_source_generate(const Edje *ed, Eina_Strbuf *buf, Eina_Bool *res)
15857 {
15858    Eina_Bool ret = *res;
15859    unsigned int i;
15860 
15861    if (!ed->collection->limits.vertical_count &&
15862        !ed->collection->limits.horizontal_count) return;
15863 
15864    BUF_APPEND(I2 "limits {\n");
15865 
15866    for (i = 0; i < ed->collection->limits.vertical_count; i++)
15867      BUF_APPENDF(I3 "vertical: \"%s\" %d;\n",
15868                  ed->collection->limits.vertical[i]->name,
15869                  ed->collection->limits.vertical[i]->value);
15870    for (i = 0; i < ed->collection->limits.horizontal_count; i++)
15871      BUF_APPENDF(I3 "horizontal: \"%s\" %d;\n",
15872                  ed->collection->limits.horizontal[i]->name,
15873                  ed->collection->limits.horizontal[i]->value);
15874 
15875    BUF_APPEND(I2 "}\n");
15876 
15877    *res = ret;
15878 }
15879 
15880 static Eina_Bool
_edje_generate_source_of_group(Edje * ed,Edje_Part_Collection_Directory_Entry * pce,Eina_Strbuf * buf)15881 _edje_generate_source_of_group(Edje *ed, Edje_Part_Collection_Directory_Entry *pce, Eina_Strbuf *buf)
15882 {
15883    Edje_Edit *eed;
15884    Eet_File *ef;
15885    Evas_Object *obj;
15886    Eina_List *l, *ll;
15887    unsigned int i;
15888    int w, h, orient;
15889    char *data;
15890    const char *group = pce->entry;
15891    Edje_Part_Collection *pc;
15892    Eina_Bool ret = EINA_TRUE, broadcast;
15893    Eina_List *alias_list = NULL;
15894    const char *alias;
15895    Eina_Iterator *it;
15896    int len;
15897    char *tmp_alias;
15898    const char *aliased;
15899    double base_scale;
15900 
15901    obj = edje_edit_object_add(ed->base.evas);
15902    if (!edje_object_file_set(obj, ed->file->path, group)) return EINA_FALSE;
15903 
15904    ef = _edje_edit_eet_open(ed, EET_FILE_MODE_READ);
15905    if (!ef)
15906      {
15907         evas_object_del(obj);
15908         return EINA_FALSE;
15909      }
15910 
15911    eed = efl_data_scope_get(obj, MY_CLASS);
15912    pc = eed->base->collection;
15913    alias_list = edje_edit_group_aliases_get(obj, group);
15914 
15915    base_scale = edje_object_base_scale_get(obj);
15916    if (fabs(base_scale - 1.0) > DBL_EPSILON)
15917      BUF_APPENDF(I1 "base_scale: \"%f\";\n",base_scale);
15918 
15919    BUF_APPENDF(I1 "group { name: \"%s\";\n", group);
15920    EINA_LIST_FOREACH(alias_list, l, data)
15921      BUF_APPENDF(I2 "alias: \"%s\";\n", data);
15922    edje_edit_string_list_free(alias_list);
15923 
15924    w = edje_edit_group_min_w_get(obj);
15925    h = edje_edit_group_min_h_get(obj);
15926    if ((w > 0) || (h > 0))
15927      BUF_APPENDF(I2 "min: %d %d;\n", w, h);
15928    w = edje_edit_group_max_w_get(obj);
15929    h = edje_edit_group_max_h_get(obj);
15930    if ((w > 0) || (h > 0))
15931      BUF_APPENDF(I2 "max: %d %d;\n", w, h);
15932 
15933    orient = edje_edit_group_orientation_get(obj);
15934    switch (orient)
15935      {
15936       case (EDJE_ORIENTATION_LTR):
15937         BUF_APPENDF(I2 "orientation: LTR;\n");
15938         break;
15939 
15940       case (EDJE_ORIENTATION_RTL):
15941         BUF_APPENDF(I2 "orientation: RTL;\n");
15942         break;
15943 
15944       case (EDJE_ORIENTATION_AUTO):
15945       default:
15946         break;
15947      }
15948    broadcast = edje_edit_group_broadcast_signal_get(obj);
15949    if (!broadcast) BUF_APPENDF(I2 "broadcast_signal: %d;\n", broadcast);
15950 
15951    /* Limits */
15952    _edje_limits_source_generate(ed, buf, &ret);
15953 
15954    if (pc->use_custom_seat_names)
15955      BUF_APPENDF(I2 "use_custom_seat_names: 1;\n");
15956 
15957    /* Data */
15958    if (pc->data)
15959      {
15960         Eina_Hash_Tuple *tuple;
15961         BUF_APPEND(I2 "data {\n");
15962 
15963         it = eina_hash_iterator_tuple_new(pc->data);
15964 
15965         if (!it)
15966           {
15967              ERR("Generating EDC for Group[%s] data.", group);
15968              return EINA_FALSE;
15969           }
15970 
15971         EINA_ITERATOR_FOREACH(it, tuple)
15972           BUF_APPENDF(I3 "item: \"%s\" \"%s\";\n", (char *)tuple->key,
15973                       edje_string_get(tuple->data));
15974 
15975         eina_iterator_free(it);
15976         BUF_APPEND(I2 "}\n");
15977      }
15978 
15979    if (eed->embryo_source)
15980      {
15981         BUF_APPEND(I2 "script {\n");
15982         BUF_APPEND(eed->embryo_source);
15983         BUF_APPEND(I2 "}\n");
15984      }
15985 
15986    /* Parts */
15987    BUF_APPEND(I2 "parts {\n");
15988    if ((pc->aliased) && (pc->alias))
15989      {
15990         it = eina_hash_iterator_data_new(pc->alias);
15991         EINA_ITERATOR_FOREACH(it, alias)
15992           {
15993              tmp_alias = strdup(alias);
15994              aliased = _edje_find_alias(pc->aliased, tmp_alias, &len);
15995              BUF_APPENDF(I3 "alias: \"%s\" \"%s\";\n", aliased, alias);
15996              free(tmp_alias);
15997           }
15998         eina_iterator_free(it);
15999      }
16000    for (i = 0; i < pc->parts_count; i++)
16001      {
16002         Edje_Part *ep;
16003         ep = pc->parts[i];
16004         ret &= _edje_generate_source_of_part(obj, ep, buf);
16005      }
16006    BUF_APPEND(I2 "}\n"); //parts
16007 
16008    if (!ret)
16009      {
16010         ERR("Generating EDC for Group[%s] Parts.", group);
16011         return EINA_FALSE;
16012      }
16013 
16014    /* Programs */
16015    if ((ll = edje_edit_programs_list_get(obj)))
16016      {
16017         BUF_APPEND(I2 "programs {\n");
16018         EINA_LIST_FOREACH(ll, l, data)
16019           ret &= _edje_generate_source_of_program(obj, data, buf);
16020         BUF_APPEND(I2 "}\n");
16021         edje_edit_string_list_free(ll);
16022      }
16023    BUF_APPEND(I1 "}\n"); //group
16024 
16025    if (!ret)
16026      {
16027         ERR("Generating EDC for Group[%s] Programs.", group);
16028         evas_object_del(obj);
16029         return EINA_FALSE;
16030      }
16031 
16032    _edje_edit_eet_close(ef);
16033    evas_object_del(obj);
16034    return ret;
16035 }
16036 
16037 static Eina_Strbuf *
_edje_generate_source(Evas_Object * obj)16038 _edje_generate_source(Evas_Object *obj)
16039 {
16040    Eina_Strbuf *buf;
16041 
16042    Eina_List *l, *ll, *ll_set;
16043    Edje_Font_Directory_Entry *fnt;
16044 
16045    char *entry;
16046    Eina_Bool ret = EINA_TRUE;
16047 
16048    GET_ED_OR_RETURN(NULL);
16049 
16050    /* Open a str buffer */
16051 
16052    buf = eina_strbuf_new();
16053    if (!buf) return NULL;
16054 
16055    /* Write edc into file */
16056    //TODO Probably we need to save the file before generation
16057 
16058    /* Images */
16059    ll_set = edje_edit_image_set_list_get(obj);
16060    ll = edje_edit_images_list_get(obj);
16061    if (ll || ll_set)
16062      {
16063         BUF_APPEND(I0 "images {\n");
16064 
16065         EINA_LIST_FOREACH(ll, l, entry)
16066           {
16067              Eina_Strbuf *gen_buf = _edje_generate_image_source(obj, entry);
16068              if (!gen_buf) continue;
16069 
16070              BUF_APPENDF(I1 "%s", eina_strbuf_string_get(gen_buf));
16071              eina_strbuf_free(gen_buf);
16072           }
16073 
16074          EINA_LIST_FOREACH(ll_set, l, entry)
16075           {
16076              Eina_Strbuf *gen_buf = _edje_generate_image_set_source(obj, entry);
16077              if (!gen_buf) continue;
16078 
16079              BUF_APPENDF("%s", eina_strbuf_string_get(gen_buf));
16080              eina_strbuf_free(gen_buf);
16081           }
16082 
16083         BUF_APPEND(I0 "}\n\n");
16084         edje_edit_string_list_free(ll);
16085         edje_edit_string_list_free(ll_set);
16086 
16087         if (!ret)
16088           {
16089              ERR("Generating EDC for Images");
16090              eina_strbuf_free(buf);
16091              return NULL;
16092           }
16093      }
16094 
16095    /* Fonts */
16096    if (ed->file->fonts)
16097      {
16098         Eina_Iterator *it;
16099 
16100         it = eina_hash_iterator_data_new(ed->file->fonts);
16101         if (it)
16102           {
16103              BUF_APPEND(I0 "fonts {\n");
16104 
16105              EINA_ITERATOR_FOREACH(it, fnt)
16106                BUF_APPENDF(I1 "font: \"%s\" \"%s\";\n", fnt->file,
16107                            fnt->entry);
16108 
16109              BUF_APPEND(I0 "}\n\n");
16110              eina_iterator_free(it);
16111 
16112              if (!ret)
16113                {
16114                   ERR("Generating EDC for Fonts");
16115                   eina_strbuf_free(buf);
16116                   return NULL;
16117                }
16118           }
16119      }
16120 
16121    /* Data */
16122    if ((ll = edje_edit_data_list_get(obj)))
16123      {
16124         BUF_APPEND(I0 "data {\n");
16125 
16126         EINA_LIST_FOREACH(ll, l, entry)
16127           BUF_APPENDF(I1 "item: \"%s\" \"%s\";\n", entry,
16128                       edje_edit_data_value_get(obj, entry));
16129 
16130         BUF_APPEND(I0 "}\n\n");
16131         edje_edit_string_list_free(ll);
16132 
16133         if (!ret)
16134           {
16135              ERR("Generating EDC for Data");
16136              eina_strbuf_free(buf);
16137              return NULL;
16138           }
16139      }
16140    /* Size Classes */
16141    if ((ll = edje_edit_size_classes_list_get(obj)))
16142      {
16143         BUF_APPEND(I0 "size_classes {\n");
16144 
16145         EINA_LIST_FOREACH(ll, l, entry)
16146           _edje_generate_source_of_sizeclass(ed, entry, buf);
16147 
16148         BUF_APPEND(I0 "}\n\n");
16149         edje_edit_string_list_free(ll);
16150 
16151         if (!ret)
16152           {
16153              ERR("Generating EDC for Size Classes");
16154              eina_strbuf_free(buf);
16155              return NULL;
16156           }
16157      }
16158 
16159    /* Text Classes */
16160    if ((ll = edje_edit_text_classes_list_get(obj)))
16161      {
16162         BUF_APPEND(I0 "text_classes {\n");
16163 
16164         EINA_LIST_FOREACH(ll, l, entry)
16165           _edje_generate_source_of_textclass(ed, entry, buf);
16166 
16167         BUF_APPEND(I0 "}\n\n");
16168         edje_edit_string_list_free(ll);
16169 
16170         if (!ret)
16171           {
16172              ERR("Generating EDC for Text Classes");
16173              eina_strbuf_free(buf);
16174              return NULL;
16175           }
16176      }
16177 
16178    /* Color Classes */
16179    if ((ll = edje_edit_color_classes_list_get(obj)))
16180      {
16181         BUF_APPEND(I0 "color_classes {\n");
16182 
16183         EINA_LIST_FOREACH(ll, l, entry)
16184           _edje_generate_source_of_colorclass(ed, entry, buf);
16185 
16186         BUF_APPEND(I0 "}\n\n");
16187         edje_edit_string_list_free(ll);
16188 
16189         if (!ret)
16190           {
16191              ERR("Generating EDC for Color Classes");
16192              eina_strbuf_free(buf);
16193              return NULL;
16194           }
16195      }
16196 
16197    /* Styles */
16198    if ((ll = edje_edit_styles_list_get(obj)))
16199      {
16200         BUF_APPEND(I0 "styles {\n");
16201         EINA_LIST_FOREACH(ll, l, entry)
16202           _edje_generate_source_of_style(ed, entry, buf);
16203         BUF_APPEND(I0 "}\n\n");
16204         edje_edit_string_list_free(ll);
16205 
16206         if (!ret)
16207           {
16208              ERR("Generating EDC for Styles");
16209              eina_strbuf_free(buf);
16210              return NULL;
16211           }
16212      }
16213 
16214    /* Externals */
16215    if ((ll = edje_edit_externals_list_get(obj)))
16216      {
16217         BUF_APPEND(I0 "externals {\n");
16218         EINA_LIST_FOREACH(ll, l, entry)
16219           BUF_APPENDF(I1 "external: \"%s\";\n", entry);
16220 
16221         BUF_APPEND(I0 "}\n\n");
16222         edje_edit_string_list_free(ll);
16223 
16224         if (!ret)
16225           {
16226              ERR("Generating EDC for Externals");
16227              eina_strbuf_free(buf);
16228              return NULL;
16229           }
16230      }
16231 
16232    /* Collections */
16233    if (ed->file->collection)
16234      {
16235         Eina_Iterator *it;
16236         Edje_Part_Collection_Directory_Entry *pce;
16237         BUF_APPEND("collections {\n");
16238 
16239         /* Sounds */
16240         if (ed->file->sound_dir)
16241           {
16242              _edje_generate_source_of_sounds(ed->file->sound_dir, buf);
16243           }
16244 
16245         it = eina_hash_iterator_data_new(ed->file->collection);
16246 
16247         if (!it)
16248           {
16249              ERR("Generating EDC for Collections");
16250              eina_strbuf_free(buf);
16251              return NULL;
16252           }
16253 
16254         EINA_ITERATOR_FOREACH(it, pce)
16255           {
16256              if (!pce->group_alias)
16257                ret &= _edje_generate_source_of_group(ed, pce, buf);
16258           }
16259 
16260         eina_iterator_free(it);
16261         BUF_APPEND("}\n\n");
16262      }
16263 
16264    return buf;
16265 }
16266 
16267 EAPI char *
edje_edit_full_source_generate(Evas_Object * obj)16268 edje_edit_full_source_generate(Evas_Object *obj)
16269 {
16270    Eina_Strbuf *code = _edje_generate_source(obj);
16271    /* return resulted source code */
16272    char *ret = eina_strbuf_string_steal(code);
16273    eina_strbuf_free(code);
16274    return ret;
16275 }
16276 
16277 /*********************/
16278 /*  SAVING ROUTINES  */
16279 /*********************/
16280 ////////////////////////////////////////
16281 typedef struct _SrcFile      SrcFile;
16282 typedef struct _SrcFile_List SrcFile_List;
16283 
16284 struct _SrcFile
16285 {
16286    char       *name;
16287    const char *file;
16288 };
16289 
16290 struct _SrcFile_List
16291 {
16292    Eina_List *list;
16293 };
16294 
16295 static Eet_Data_Descriptor *_srcfile_edd = NULL;
16296 static Eet_Data_Descriptor *_srcfile_list_edd = NULL;
16297 
16298 static void
source_edd(void)16299 source_edd(void)
16300 {
16301    Eet_Data_Descriptor_Class eddc;
16302 
16303    if (_srcfile_edd) return;
16304 
16305    eet_eina_stream_data_descriptor_class_set(&eddc, sizeof (eddc), "srcfile", sizeof(SrcFile));
16306    _srcfile_edd = eet_data_descriptor_stream_new(&eddc);
16307    EET_DATA_DESCRIPTOR_ADD_BASIC(_srcfile_edd, SrcFile, "name", name, EET_T_INLINED_STRING);
16308    EET_DATA_DESCRIPTOR_ADD_BASIC(_srcfile_edd, SrcFile, "file", file, EET_T_INLINED_STRING);
16309 
16310    eet_eina_stream_data_descriptor_class_set(&eddc, sizeof (eddc), "srcfile_list", sizeof(SrcFile_List));
16311    _srcfile_list_edd = eet_data_descriptor_stream_new(&eddc);
16312    EET_DATA_DESCRIPTOR_ADD_LIST(_srcfile_list_edd, SrcFile_List, "list", list, _srcfile_edd);
16313 }
16314 
16315 /////////////////////////////////////////
16316 
16317 static Eina_Bool
_edje_edit_edje_file_save(Eet_File * eetf,Edje_File * ef)16318 _edje_edit_edje_file_save(Eet_File *eetf, Edje_File *ef)
16319 {
16320    /* Write Edje_File structure */
16321    INF("** Writing Edje_File* ed->file");
16322    if (eet_data_write(eetf, _edje_edd_edje_file, "edje/file", ef, 1) <= 0)
16323      {
16324         ERR("Error. unable to write \"edje_file\" entry to \"%s\"", ef->path);
16325         return EINA_FALSE;
16326      }
16327    return EINA_TRUE;
16328 }
16329 
16330 static Eina_Bool
_edje_edit_collection_save(Eet_File * eetf,Edje_Part_Collection * epc)16331 _edje_edit_collection_save(Eet_File *eetf, Edje_Part_Collection *epc)
16332 {
16333    char buf[256];
16334 
16335    snprintf(buf, sizeof(buf), "edje/collections/%i", epc->id);
16336 
16337    if (eet_data_write(eetf, _edje_edd_edje_part_collection, buf, epc, 1) > 0)
16338      return EINA_TRUE;
16339 
16340    ERR("Error. unable to write \"%s\" part entry", buf);
16341    return EINA_FALSE;
16342 }
16343 
16344 static Eina_Bool
_edje_edit_source_save(Eet_File * eetf,Evas_Object * obj)16345 _edje_edit_source_save(Eet_File *eetf, Evas_Object *obj)
16346 {
16347    SrcFile *sf;
16348    SrcFile_List *sfl;
16349    Eina_Strbuf *source_file;
16350    Eina_Bool ret = EINA_TRUE;
16351 
16352    source_file = _edje_generate_source(obj);
16353    if (!source_file)
16354      {
16355         ERR("Can't create edc source");
16356         return EINA_FALSE;
16357      }
16358 
16359    //open the temp file and put the contents in SrcFile
16360    sf = _alloc(sizeof(SrcFile));
16361    if (!sf)
16362      {
16363         ERR("Unable to create source file struct");
16364         ret = EINA_FALSE;
16365         goto save_free_source;
16366      }
16367    sf->name = strdup("generated_source.edc");
16368    if (!sf->name)
16369      {
16370         ERR("Unable to alloc filename");
16371         ret = EINA_FALSE;
16372         goto save_free_sf;
16373      }
16374 
16375    sf->file = eina_strbuf_string_get(source_file);
16376 
16377    //create the needed list of source files (only one)
16378    sfl = _alloc(sizeof(SrcFile_List));
16379    if (!sfl)
16380      {
16381         ERR("Unable to create file list");
16382         ret = EINA_FALSE;
16383         goto save_free_filename;
16384      }
16385    sfl->list = NULL;
16386    sfl->list = eina_list_append(sfl->list, sf);
16387    if (!sfl->list)
16388      {
16389         ERR("Error. unable to append file in list");
16390         ret = EINA_FALSE;
16391         goto save_free_sfl;
16392      }
16393 
16394    // write the sources list to the eet file
16395    source_edd();
16396    if (eet_data_write(eetf, _srcfile_list_edd, "edje_sources", sfl, 1) <= 0)
16397      {
16398         ERR("Unable to write edc source");
16399         ret = EINA_FALSE;
16400      }
16401 
16402    /* Clear stuff */
16403    eina_list_free(sfl->list);
16404 save_free_sfl:
16405    free(sfl);
16406 save_free_filename:
16407    free(sf->name);
16408 save_free_sf:
16409    free(sf);
16410 save_free_source:
16411    eina_strbuf_free(source_file);
16412    return ret;
16413 }
16414 
16415 Eina_Bool
_edje_edit_internal_save(Evas_Object * obj,int current_only,Eina_Bool generate_source)16416 _edje_edit_internal_save(Evas_Object *obj, int current_only, Eina_Bool generate_source)
16417 {
16418    Edje_File *ef;
16419    Eet_File *eetf;
16420 
16421    GET_EED_OR_RETURN(EINA_FALSE);
16422    GET_ED_OR_RETURN(EINA_FALSE);
16423 
16424    ef = ed->file;
16425    if (!ef) return EINA_FALSE;
16426 
16427    INF("***********  Saving file ******************");
16428    INF("** path: %s", ef->path);
16429 
16430    /* Open the eet file */
16431    eetf = _edje_edit_eet_open(ed, EET_FILE_MODE_READ_WRITE);
16432    if (!eetf)
16433      return EINA_FALSE;
16434 
16435    /* Set compiler name */
16436    if (strcmp(ef->compiler, "edje_edit"))
16437      _edje_if_string_replace(ed, &ef->compiler, "edje_edit");
16438 
16439    if (!_edje_edit_edje_file_save(eetf, ef))
16440      {
16441         _edje_edit_eet_close(eetf);
16442         return EINA_FALSE;
16443      }
16444 
16445    if (current_only)
16446      {
16447         if (ed->collection)
16448           {
16449              INF("** Writing Edje_Part_Collection* ed->collection "
16450                  "[id: %d]", ed->collection->id);
16451              if (!_edje_edit_collection_save(eetf, ed->collection))
16452                {
16453                   _edje_edit_eet_close(eetf);
16454                   return EINA_FALSE;
16455                }
16456           }
16457      }
16458    else
16459      {
16460         Eina_List *l;
16461         Edje_Part_Collection *edc;
16462         Edje_Part_Collection_Directory_Entry *ce;
16463         Eina_Iterator *it;
16464 
16465         INF("** Writing all collections");
16466 
16467         EINA_LIST_FOREACH(ef->collection_cache, l, edc)
16468           {
16469              INF("** Writing cache Edje_Part_Collection* ed->collection "
16470                  "[id: %d]", edc->id);
16471              if (!_edje_edit_collection_save(eetf, edc))
16472                {
16473                   _edje_edit_eet_close(eetf);
16474                   return EINA_FALSE;
16475                }
16476           }
16477 
16478         it = eina_hash_iterator_data_new(ef->collection);
16479         while (eina_iterator_next(it, (void **)&ce))
16480           {
16481              if (ce->ref)
16482                {
16483                   INF("** Writing hash Edje_Part_Collection* ed->collection "
16484                       "[id: %d]", ce->id);
16485                   if (!_edje_edit_collection_save(eetf, ce->ref))
16486                     {
16487                        _edje_edit_eet_close(eetf);
16488                        return EINA_FALSE;
16489                     }
16490                }
16491           }
16492         eina_iterator_free(it);
16493      }
16494 
16495    if ((eed->bytecode_dirty || eed->script_need_recompile) && ed->collection)
16496      {
16497         char buf[64];
16498         Eina_Iterator *it;
16499         Program_Script *ps;
16500         Eina_List *deathnote = NULL;
16501 
16502         if (eed->bytecode_dirty)
16503           {
16504              snprintf(buf, sizeof(buf), "edje/scripts/embryo/compiled/%i",
16505                       ed->collection->id);
16506              eet_write(eetf, buf, eed->bytecode, eed->bytecode_size, 1);
16507              free(eed->bytecode);
16508              eed->bytecode = NULL;
16509              eed->bytecode_size = 0;
16510              eed->bytecode_dirty = EINA_FALSE;
16511           }
16512 
16513         if (eed->embryo_source_dirty)
16514           {
16515              snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%i",
16516                       ed->collection->id);
16517              eet_write(eetf, buf, eed->embryo_source,
16518                        strlen(eed->embryo_source) + 1, 1);
16519              eed->embryo_source_dirty = EINA_FALSE;
16520           }
16521 
16522         it = eina_hash_iterator_data_new(eed->program_scripts);
16523         EINA_ITERATOR_FOREACH(it, ps)
16524           {
16525              if (ps->dirty)
16526                {
16527                   snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%i/%i",
16528                            ed->collection->id, ps->id);
16529                   eet_write(eetf, buf, ps->code, strlen(ps->code) + 1, 1);
16530                   ps->dirty = EINA_FALSE;
16531                }
16532              else if (ps->delete_me)
16533                {
16534                   snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%i/%i",
16535                            ed->collection->id, ps->id);
16536                   eet_delete(eetf, buf);
16537                   deathnote = eina_list_append(deathnote, ps);
16538                }
16539           }
16540         eina_iterator_free(it);
16541 
16542         EINA_LIST_FREE(deathnote, ps)
16543           eina_hash_del(eed->program_scripts, &ps->id, ps);
16544      }
16545 
16546    if (generate_source)
16547      if (!_edje_edit_source_save(eetf, obj))
16548        {
16549           _edje_edit_eet_close(eetf);
16550           return EINA_FALSE;
16551        }
16552 
16553    _edje_edit_eet_close(eetf);
16554 
16555    /* Update mtime */
16556    {
16557       struct stat st;
16558       if (stat(ed->path, &st) != 0)
16559         return EINA_FALSE;
16560       ef->mtime = st.st_mtime;
16561    }
16562 
16563    INF("***********  Saving DONE ******************");
16564    return EINA_TRUE;
16565 }
16566 
16567 EAPI Eina_Bool
edje_edit_clean_save_as(Evas_Object * obj,const char * new_file_name)16568 edje_edit_clean_save_as(Evas_Object *obj, const char *new_file_name)
16569 {
16570    Eet_File *ef, *ef_out;
16571    GET_ED_OR_RETURN(EINA_FALSE);
16572    GET_EED_OR_RETURN(EINA_FALSE);
16573 
16574    if (!ed->file) return EINA_FALSE;
16575 
16576    if (ecore_file_exists(new_file_name))
16577      {
16578         ERR("Error. file \"%s\" already exists",
16579             new_file_name);
16580         return EINA_FALSE;
16581      }
16582    ef = _edje_edit_eet_open(ed, EET_FILE_MODE_READ);
16583    if (!ef)
16584      return EINA_FALSE;
16585    ef_out = eet_open(new_file_name, EET_FILE_MODE_WRITE);
16586    if (!ef_out)
16587      {
16588         ERR("Error. unable to open \"%s\" for writing output",
16589             new_file_name);
16590         _edje_edit_eet_close(ef);
16591         return EINA_FALSE;
16592      }
16593 
16594    /* copying file structure */
16595    if (!_edje_edit_edje_file_save(ef_out, ed->file))
16596      {
16597         _edje_edit_eet_close(ef);
16598         eet_close(ef_out);
16599         return EINA_FALSE;
16600      }
16601 
16602    int count = 0;
16603    char **ent;
16604    int i;
16605    int size = 0;
16606    const void *data;
16607 
16608    ent = eet_list(ef, "*", &count);
16609    if (ent)
16610      {
16611         /* copying data */
16612         for (i = 0; i < count; i++)
16613           {
16614              /* Skiping entries that need special saving */
16615              if (!strcmp(ent[i], "edje/file")) continue;
16616              if (!strcmp(ent[i], "edje_sources")) continue;
16617              if (strstr(ent[i], "collection")) continue;
16618 
16619              data = eet_read_direct(ef, ent[i], &size);
16620              if (data) eet_write(ef_out, ent[i], data, size, 0);
16621              else
16622                {
16623                   data = eet_read(ef, ent[i], &size);
16624                   eet_write(ef_out, ent[i], data, size, 1);
16625                }
16626           }
16627         free(ent);
16628      }
16629 
16630    /* copying groups */
16631    Edje_Part_Collection_Directory_Entry *ce;
16632    Evas_Object *part_obj;
16633    part_obj = edje_edit_object_add(ed->base.evas);
16634    Eina_Iterator *it = eina_hash_iterator_data_new(ed->file->collection);
16635    EINA_ITERATOR_FOREACH(it, ce)
16636      {
16637         /* forcing collection load into memory */
16638         edje_object_file_set(part_obj, ed->file->path, ce->entry);
16639 
16640         _edje_edit_collection_save(ef_out, ce->ref);
16641      }
16642    eina_iterator_free(it);
16643 
16644    /* generating source code */
16645    _edje_edit_source_save(ef_out, obj);
16646 
16647    _edje_edit_eet_close(ef);
16648    eet_close(ef_out);
16649 
16650    return EINA_TRUE;
16651 }
16652 
16653 EAPI Eina_Bool
edje_edit_save(Evas_Object * obj)16654 edje_edit_save(Evas_Object *obj)
16655 {
16656    return _edje_edit_internal_save(obj, 1, EINA_TRUE);
16657 }
16658 
16659 EAPI Eina_Bool
edje_edit_save_all(Evas_Object * obj)16660 edje_edit_save_all(Evas_Object *obj)
16661 {
16662    return _edje_edit_internal_save(obj, 0, EINA_TRUE);
16663 }
16664 
16665 EAPI Eina_Bool
edje_edit_without_source_save(Evas_Object * obj,Eina_Bool current_group)16666 edje_edit_without_source_save(Evas_Object *obj, Eina_Bool current_group)
16667 {
16668    GET_ED_OR_RETURN(EINA_FALSE);
16669    Eet_File *eetf = NULL;
16670    SrcFile_List *sfl = NULL;
16671 
16672    if (!_edje_edit_internal_save(obj, current_group, EINA_FALSE))
16673      {
16674         ERR("Unable save binary data into file");
16675         return EINA_FALSE;
16676      }
16677 
16678    sfl = _alloc(sizeof(SrcFile_List));
16679    if (!sfl)
16680      {
16681         ERR("Unable to create file list");
16682         return EINA_FALSE;
16683      }
16684    sfl->list = NULL;
16685    eetf = _edje_edit_eet_open(ed, EET_FILE_MODE_READ_WRITE);
16686    if (!eetf)
16687      {
16688         free(sfl);
16689         return EINA_FALSE;
16690      }
16691    source_edd();
16692    if (eet_data_write(eetf, _srcfile_list_edd, "edje_sources", sfl, 1) <= 0)
16693      {
16694         ERR("Unable to clean edc source from edj file");
16695         free(sfl);
16696         _edje_edit_eet_close(eetf);
16697         return EINA_FALSE;
16698      }
16699 
16700    free(sfl);
16701    _edje_edit_eet_close(eetf);
16702    return EINA_TRUE;
16703 }
16704 
16705 EAPI void
edje_edit_print_internal_status(Evas_Object * obj)16706 edje_edit_print_internal_status(Evas_Object *obj)
16707 {
16708 /*
16709    Edje_Program *epr;
16710    unsigned int i;
16711    int j;
16712  */
16713    Eina_Strbuf *source_file;
16714    GET_EED_OR_RETURN();
16715 
16716    source_file = _edje_generate_source(obj);
16717    if (source_file) eina_strbuf_free(source_file);
16718 /*
16719    INF("****** CHECKIN' INTERNAL STRUCTS STATUS *********");
16720 
16721    INF("path: '%s', group: '%s', parent: '%s'",
16722        ed->path, ed->group, ed->parent);
16723 
16724    INF("Parts [table:%d list:%d]", ed->table_parts_size,
16725        ed->collection->parts_count);
16726    for (i = 0; i < ed->collection->parts_count; ++i)
16727      {
16728         Edje_Real_Part *rp;
16729         Edje_Part *p;
16730 
16731         p = ed->collection->parts[i];
16732 
16733         rp = ed->table_parts[p->id % ed->table_parts_size];
16734         printf("part[%d]: '%s' ", p->id, p->name);
16735         if (p == rp->part)
16736           printf("OK!\n");
16737         else
16738           printf("WRONG (table[%d]->name = '%s')\n", p->id, rp->part->name);
16739      }
16740 
16741    INF("Programs [table:%d list:%d,%d,%d,%d,%d]", ed->table_programs_size,
16742        ed->collection->programs.fnmatch_count,
16743        ed->collection->programs.strcmp_count,
16744        ed->collection->programs.strncmp_count,
16745        ed->collection->programs.strrncmp_count,
16746        ed->collection->programs.nocmp_count);
16747    for(j = 0; j < ed->table_programs_size; ++j)
16748      {
16749         epr = ed->table_programs[i % ed->table_programs_size];
16750         printf("program[%d]: '%s'\n", epr->id, epr->name);
16751      }
16752 
16753    INF("******************  END  ************************");
16754  */
16755 }
16756 
16757 /* Internal EO APIs and hidden overrides */
16758 
16759 #define EDJE_EDIT_EXTRA_OPS \
16760    EFL_CANVAS_GROUP_DEL_OPS(edje_edit)
16761 
16762 #include "edje_edit_eo.c"
16763