update for beta release
[framework/uifw/e17.git] / src / modules / conf_theme / e_int_config_theme.c
1 #include "e.h"
2 #include "e_int_config_theme_import.h"
3 #include "e_int_config_theme_web.h"
4
5 static void *_create_data(E_Config_Dialog *cfd);
6 static void _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
7 static void _fill_data(E_Config_Dialog_Data *cfdata);
8 static int _basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
9 static Evas_Object *_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
10 static int _advanced_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
11 static Evas_Object *_advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
12 static Eina_List *_get_theme_categories_list(void);
13
14 struct _E_Config_Dialog_Data
15 {
16    E_Config_Dialog *cfd;
17
18    /* Basic */
19    Evas_Object *o_fm;
20    Evas_Object *o_up_button;
21    Evas_Object *o_preview;
22    Evas_Object *o_personal;
23    Evas_Object *o_system;
24    int fmdir;
25    const char *theme;
26
27    /* Advanced */
28    Evas_Object *o_categories_ilist;
29    Evas_Object *o_files_ilist;
30    int personal_file_count;
31    Eina_List *theme_list;
32    Eina_List *parts_list;
33
34    /* Dialog */
35    E_Win *win_import;
36    E_Dialog *dia_web;
37 };
38
39 static const char *parts_list[] =
40 {
41    "about:e/widgets/about/main",
42      "borders:e/widgets/border/default/border",
43      "background:e/desktop/background",
44      "configure:e/widgets/configure/main",
45      "dialog:e/widgets/dialog/main",
46      "dnd:ZZZ",
47      "error:e/error/main",
48      "exebuf:e/widgets/exebuf/main",
49      "fileman:ZZZ",
50      "gadman:e/gadman/control",
51      "icons:ZZZ",
52      "menus:ZZZ",
53      "modules:ZZZ",
54      "modules/pager:e/widgets/pager/popup",
55      "modules/ibar:ZZZ",
56      "modules/ibox:ZZZ",
57      "modules/clock:e/modules/clock/main",
58      "modules/battery:e/modules/battery/main",
59      "modules/cpufreq:e/modules/cpufreq/main",
60      "modules/start:e/modules/start/main",
61      "modules/temperature:e/modules/temperature/main",
62      "pointer:e/pointer",
63      "shelf:e/shelf/default/base",
64      "transitions:ZZZ",
65      "widgets:ZZZ",
66      "winlist:e/widgets/winlist/main",
67      NULL
68 };
69
70 E_Config_Dialog *
71 e_int_config_theme(E_Container *con, const char *params __UNUSED__)
72 {
73    E_Config_Dialog *cfd;
74    E_Config_Dialog_View *v;
75
76    if (e_config_dialog_find("E", "appearance/theme")) return NULL;
77    v = E_NEW(E_Config_Dialog_View, 1);
78
79    v->create_cfdata = _create_data;
80    v->free_cfdata = _free_data;
81    v->basic.apply_cfdata = _basic_apply_data;
82    v->basic.create_widgets = _basic_create_widgets;
83    v->advanced.apply_cfdata = _advanced_apply_data;
84    v->advanced.create_widgets = _advanced_create_widgets;
85    v->override_auto_apply = 1;
86    cfd = e_config_dialog_new(con,
87                              _("Theme Selector"),
88                              "E", "appearance/theme",
89                              "preferences-desktop-theme", 0, v, NULL);
90    return cfd;
91 }
92
93 void
94 e_int_config_theme_import_done(E_Config_Dialog *dia)
95 {
96    E_Config_Dialog_Data *cfdata;
97
98    cfdata = dia->cfdata;
99    cfdata->win_import = NULL;
100 }
101
102 void
103 e_int_config_theme_web_done(E_Config_Dialog *dia)
104 {
105    E_Config_Dialog_Data *cfdata;
106
107    cfdata = dia->cfdata;
108    cfdata->dia_web = NULL;
109 }
110
111 void
112 e_int_config_theme_update(E_Config_Dialog *dia, char *file)
113 {
114    E_Config_Dialog_Data *cfdata;
115    char path[4096];
116
117    cfdata = dia->cfdata;
118
119    cfdata->fmdir = 1;
120    e_widget_radio_toggle_set(cfdata->o_personal, 1);
121
122    e_user_dir_concat_static(path, "themes");
123    eina_stringshare_del(cfdata->theme);
124    cfdata->theme = eina_stringshare_add(file);
125
126    if (cfdata->o_fm)
127      e_widget_flist_path_set(cfdata->o_fm, path, "/");
128
129    if (cfdata->o_preview)
130      e_widget_preview_edje_set(cfdata->o_preview, cfdata->theme,
131                                "e/desktop/background");
132    if (cfdata->o_fm) e_widget_change(cfdata->o_fm);
133 }
134
135 static void
136 _cb_button_up(void *data1, void *data2 __UNUSED__)
137 {
138    E_Config_Dialog_Data *cfdata;
139
140    cfdata = data1;
141    if (cfdata->o_fm) e_widget_flist_parent_go(cfdata->o_fm);
142 }
143
144 static void
145 _cb_files_changed(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
146 {
147    E_Config_Dialog_Data *cfdata;
148
149    cfdata = data;
150    if (!cfdata->o_fm) return;
151    if (cfdata->o_up_button)
152      e_widget_disabled_set(cfdata->o_up_button,
153                            !e_widget_flist_has_parent_get(cfdata->o_fm));
154 }
155
156 static void
157 _cb_files_selection_change(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
158 {
159    E_Config_Dialog_Data *cfdata;
160    Eina_List *selected;
161    E_Fm2_Icon_Info *ici;
162    const char *realpath;
163    char buf[4096];
164
165    cfdata = data;
166    if (!cfdata->o_fm) return;
167
168    if (!(selected = e_widget_flist_selected_list_get(cfdata->o_fm))) return;
169
170    ici = selected->data;
171    realpath = e_widget_flist_real_path_get(cfdata->o_fm);
172
173    if (!strcmp(realpath, "/"))
174      snprintf(buf, sizeof(buf), "/%s", ici->file);
175    else
176      snprintf(buf, sizeof(buf), "%s/%s", realpath, ici->file);
177    eina_list_free(selected);
178
179    if (ecore_file_is_dir(buf)) return;
180
181    eina_stringshare_del(cfdata->theme);
182    cfdata->theme = eina_stringshare_add(buf);
183    if (cfdata->o_preview)
184      e_widget_preview_edje_set(cfdata->o_preview, buf, "e/desktop/background");
185    if (cfdata->o_fm) e_widget_change(cfdata->o_fm);
186 }
187
188 #if 0
189 /* FIXME unused */
190 static void
191 _cb_files_selected(void *data, Evas_Object *obj, void *event_info)
192 {
193    E_Config_Dialog_Data *cfdata;
194
195    cfdata = data;
196 }
197 #endif
198
199 static void
200 _cb_files_files_changed(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
201 {
202    E_Config_Dialog_Data *cfdata;
203    const char *p;
204    char buf[4096];
205    size_t len;
206
207    cfdata = data;
208    if ((!cfdata->theme) || (!cfdata->o_fm)) return;
209
210    p = e_widget_flist_real_path_get(cfdata->o_fm);
211    if (p)
212      {
213         if (strncmp(p, cfdata->theme, strlen(p))) return;
214      }
215    if (!p) return;
216
217    len = e_user_dir_concat_static(buf, "themes");
218    if (!strncmp(cfdata->theme, buf, len))
219      p = cfdata->theme + len + 1;
220    else
221      {
222         len = e_prefix_data_concat_static(buf, "data/themes");
223         if (!strncmp(cfdata->theme, buf, len))
224           p = cfdata->theme + len + 1;
225         else
226           p = cfdata->theme;
227      }
228    e_widget_flist_select_set(cfdata->o_fm, p, 1);
229    e_widget_flist_file_show(cfdata->o_fm, p);
230 }
231
232 static void
233 _cb_dir(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
234 {
235    E_Config_Dialog_Data *cfdata;
236    char path[4096];
237
238    cfdata = data;
239    if (cfdata->fmdir == 1)
240      e_prefix_data_concat_static(path, "data/themes");
241    else
242      e_user_dir_concat_static(path, "themes");
243    e_widget_flist_path_set(cfdata->o_fm, path, "/");
244 }
245
246 static void
247 _cb_files_files_deleted(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
248 {
249    E_Config_Dialog_Data *cfdata;
250    Eina_List *sel, *all, *n;
251    E_Fm2_Icon_Info *ici, *ic;
252
253    cfdata = data;
254    if ((!cfdata->theme) || (!cfdata->o_fm)) return;
255
256    if (!(all = e_widget_flist_all_list_get(cfdata->o_fm))) return;
257    if (!(sel = e_widget_flist_selected_list_get(cfdata->o_fm))) return;
258
259    ici = sel->data;
260
261    all = eina_list_data_find_list(all, ici);
262    n = eina_list_next(all);
263    if (!n)
264      {
265         n = eina_list_prev(all);
266         if (!n) return;
267      }
268
269    if (!(ic = n->data)) return;
270
271    e_widget_flist_select_set(cfdata->o_fm, ic->file, 1);
272    e_widget_flist_file_show(cfdata->o_fm, ic->file);
273
274    eina_list_free(n);
275
276    evas_object_smart_callback_call(cfdata->o_fm, "selection_change", cfdata);
277 }
278
279 static void
280 _cb_import(void *data1, void *data2 __UNUSED__)
281 {
282    E_Config_Dialog_Data *cfdata;
283
284    cfdata = data1;
285    if (cfdata->win_import)
286      e_win_raise(cfdata->win_import);
287    else
288      cfdata->win_import = e_int_config_theme_import(cfdata->cfd);
289 }
290
291 #ifdef HAVE_EXCHANGE
292 static void
293 _cb_web(void *data1, void *data2 __UNUSED__)
294 {
295    E_Config_Dialog_Data *cfdata;
296
297    cfdata = data1;
298    if (cfdata->dia_web)
299      e_win_raise(cfdata->dia_web->win);
300    else
301      cfdata->dia_web = e_int_config_theme_web(cfdata->cfd);
302 }
303 #endif
304
305 static void
306 _fill_data(E_Config_Dialog_Data *cfdata)
307 {
308    E_Config_Theme * c;
309    char path[4096];
310    size_t len;
311
312    c = e_theme_config_get("theme");
313    if (c)
314      cfdata->theme = eina_stringshare_add(c->file);
315    else
316      {
317         e_prefix_data_concat_static(path, "data/themes/default.edj");
318         cfdata->theme = eina_stringshare_add(path);
319      }
320    if (cfdata->theme[0] != '/')
321      {
322         e_user_dir_snprintf(path, sizeof(path), "themes/%s", cfdata->theme);
323         if (ecore_file_exists(path))
324           {
325              eina_stringshare_del(cfdata->theme);
326              cfdata->theme = eina_stringshare_add(path);
327           }
328         else
329           {
330              e_prefix_data_snprintf(path, sizeof(path), "data/themes/%s",
331                                     cfdata->theme);
332              if (ecore_file_exists(path))
333                {
334                   eina_stringshare_del(cfdata->theme);
335                   cfdata->theme = eina_stringshare_add(path);
336                }
337           }
338      }
339
340    cfdata->theme_list = _get_theme_categories_list();
341
342    len = e_prefix_data_concat_static(path, "data/themes");
343    if (!strncmp(cfdata->theme, path, len))
344      cfdata->fmdir = 1;
345 }
346
347 static void *
348 _create_data(E_Config_Dialog *cfd)
349 {
350    E_Config_Dialog_Data *cfdata;
351
352    cfdata = E_NEW(E_Config_Dialog_Data, 1);
353    cfd->cfdata = cfdata;
354    cfdata->cfd = cfd;
355    _fill_data(cfdata);
356    return cfdata;
357 }
358
359 static void
360 _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
361 {
362    E_Config_Theme *t;
363
364    if (cfdata->win_import)
365      e_int_config_theme_del(cfdata->win_import);
366
367    EINA_LIST_FREE(cfdata->theme_list, t)
368      {
369         eina_stringshare_del(t->file);
370         eina_stringshare_del(t->category);
371         free(t);
372      }
373
374    E_FREE(cfdata);
375 }
376
377 static Evas_Object *
378 _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
379 {
380    Evas_Object *o, *ot, *of, *il, *ol;
381    E_Zone *z;
382    E_Radio_Group *rg;
383    char path[4096];
384
385    z = e_zone_current_get(cfd->con);
386
387    ot = e_widget_table_add(evas, 0);
388    ol = e_widget_table_add(evas, 0);
389    il = e_widget_table_add(evas, 1);
390
391    rg = e_widget_radio_group_new(&(cfdata->fmdir));
392    o = e_widget_radio_add(evas, _("Personal"), 0, rg);
393    cfdata->o_personal = o;
394    evas_object_smart_callback_add(o, "changed", _cb_dir, cfdata);
395    e_widget_table_object_append(il, o, 0, 0, 1, 1, 1, 1, 0, 0);
396    o = e_widget_radio_add(evas, _("System"), 1, rg);
397    cfdata->o_system = o;
398    evas_object_smart_callback_add(o, "changed", _cb_dir, cfdata);
399    e_widget_table_object_append(il, o, 1, 0, 1, 1, 1, 1, 0, 0);
400
401    e_widget_table_object_append(ol, il, 0, 0, 1, 1, 0, 0, 0, 0);
402
403    o = e_widget_button_add(evas, _("Go up a Directory"), "go-up",
404                            _cb_button_up, cfdata, NULL);
405    cfdata->o_up_button = o;
406    e_widget_table_object_append(ol, o, 0, 1, 1, 1, 0, 0, 0, 0);
407
408    if (cfdata->fmdir == 1)
409      e_prefix_data_concat_static(path, "data/themes");
410    else
411      e_user_dir_concat_static(path, "themes");
412
413    o = e_widget_flist_add(evas);
414    cfdata->o_fm = o;
415    evas_object_smart_callback_add(o, "dir_changed",
416                                   _cb_files_changed, cfdata);
417    evas_object_smart_callback_add(o, "selection_change",
418                                   _cb_files_selection_change, cfdata);
419    evas_object_smart_callback_add(o, "changed",
420                                   _cb_files_files_changed, cfdata);
421    evas_object_smart_callback_add(o, "files_deleted",
422                                   _cb_files_files_deleted, cfdata);
423    e_widget_flist_path_set(o, path, "/");
424
425    e_widget_size_min_set(o, 160, 160);
426    e_widget_table_object_append(ol, o, 0, 2, 1, 1, 1, 1, 1, 1);
427    e_widget_table_object_append(ot, ol, 0, 0, 1, 1, 1, 1, 1, 1);
428
429    of = e_widget_list_add(evas, 0, 0);
430
431    il = e_widget_list_add(evas, 0, 1);
432    o = e_widget_button_add(evas, _(" Import..."), "preferences-desktop-theme",
433                            _cb_import, cfdata, NULL);
434    e_widget_list_object_append(il, o, 1, 0, 0.5);
435 #ifdef HAVE_EXCHANGE
436    o = e_widget_button_add(evas, _(" Online..."), "network-website",
437                            _cb_web, cfdata, NULL);
438    e_widget_list_object_append(il, o, 1, 0, 0.5);
439 #endif
440    e_widget_list_object_append(of, il, 1, 0, 0.0);
441
442    {
443       Evas_Object *oa;
444       int mw, mh;
445
446       mw = 320;
447       mh = (mw * z->h) / z->w;
448       oa = e_widget_aspect_add(evas, mw, mh);
449       o = e_widget_preview_add(evas, mw, mh);
450       evas_object_size_hint_min_set(o, mw, mh);
451       cfdata->o_preview = o;
452       if (cfdata->theme)
453         e_widget_preview_edje_set(o, cfdata->theme, "e/desktop/background");
454       e_widget_aspect_child_set(oa, o);
455       e_widget_list_object_append(of, oa, 1, 1, 0);
456       evas_object_show(o);
457       evas_object_show(oa);
458    }
459    e_widget_table_object_append(ot, of, 1, 0, 1, 1, 1, 1, 1, 1);
460
461    e_dialog_resizable_set(cfd->dia, 1);
462    return ot;
463 }
464
465 static int
466 _basic_apply_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
467 {
468    E_Action *a;
469    E_Config_Theme *ct;
470
471    /* Actually take our cfdata settings and apply them in real life */
472    ct = e_theme_config_get("theme");
473    if ((ct) && (!strcmp(ct->file, cfdata->theme))) return 1;
474
475    e_theme_config_set("theme", cfdata->theme);
476    e_config_save_queue();
477
478    a = e_action_find("restart");
479    if ((a) && (a->func.go)) a->func.go(NULL, NULL);
480    return 1; /* Apply was OK */
481 }
482
483 /*
484  * --------------------------------------
485  * --- A D V A N C E D  S U P P O R T ---
486  * --------------------------------------
487  */
488
489 static int
490 _cb_sort(const void *data1, const void *data2)
491 {
492    const char *d1, *d2;
493
494    d1 = data1;
495    d2 = data2;
496    if (!d1) return 1;
497    if (!d2) return -1;
498
499    return strcmp(d1, d2);
500 }
501
502 static Eina_List *
503 _get_theme_categories_list(void)
504 {
505    Eina_List *themes, *tcl = NULL;
506    Eina_List *cats = NULL, *g = NULL, *cats2 = NULL;
507    const char *c;
508    char *category;
509
510    /* Setup some default theme categories */
511    cats = eina_list_append(cats, eina_stringshare_add("base/theme/about"));
512    cats = eina_list_append(cats, eina_stringshare_add("base/theme/borders"));
513    cats = eina_list_append(cats, eina_stringshare_add("base/theme/background"));
514    cats = eina_list_append(cats, eina_stringshare_add("base/theme/configure"));
515    cats = eina_list_append(cats, eina_stringshare_add("base/theme/dialog"));
516    cats = eina_list_append(cats, eina_stringshare_add("base/theme/dnd"));
517    cats = eina_list_append(cats, eina_stringshare_add("base/theme/error"));
518    cats = eina_list_append(cats, eina_stringshare_add("base/theme/exebuf"));
519    cats = eina_list_append(cats, eina_stringshare_add("base/theme/fileman"));
520    cats = eina_list_append(cats, eina_stringshare_add("base/theme/gadman"));
521    cats = eina_list_append(cats, eina_stringshare_add("base/theme/icons"));
522    cats = eina_list_append(cats, eina_stringshare_add("base/theme/menus"));
523    cats = eina_list_append(cats, eina_stringshare_add("base/theme/modules"));
524    cats = eina_list_append(cats, eina_stringshare_add("base/theme/modules/pager"));
525    cats = eina_list_append(cats, eina_stringshare_add("base/theme/modules/ibar"));
526    cats = eina_list_append(cats, eina_stringshare_add("base/theme/modules/ibox"));
527    cats = eina_list_append(cats, eina_stringshare_add("base/theme/modules/clock"));
528    cats = eina_list_append(cats, eina_stringshare_add("base/theme/modules/battery"));
529    cats = eina_list_append(cats, eina_stringshare_add("base/theme/modules/cpufreq"));
530    cats = eina_list_append(cats, eina_stringshare_add("base/theme/modules/start"));
531    cats = eina_list_append(cats, eina_stringshare_add("base/theme/modules/temperature"));
532    cats = eina_list_append(cats, eina_stringshare_add("base/theme/pointer"));
533    cats = eina_list_append(cats, eina_stringshare_add("base/theme/shelf"));
534    cats = eina_list_append(cats, eina_stringshare_add("base/theme/transitions"));
535    cats = eina_list_append(cats, eina_stringshare_add("base/theme/widgets"));
536    cats = eina_list_append(cats, eina_stringshare_add("base/theme/winlist"));
537
538    cats = eina_list_sort(cats, 0, _cb_sort);
539
540    /*
541     * Get a list of registered themes.
542     * Add those which are not in the above list
543     */
544    EINA_LIST_FOREACH(e_theme_category_list(), g, c)
545      {
546         int res;
547
548         if (!c) continue;
549
550         cats2 = eina_list_search_sorted_near_list(cats, _cb_sort, c, &res);
551         if (!res) continue;
552         if (res < 0)
553           cats = eina_list_prepend_relative_list(cats, eina_stringshare_ref(c), cats2);
554         else
555           cats = eina_list_append_relative_list(cats, eina_stringshare_ref(c), cats2);
556      }
557
558    EINA_LIST_FREE(cats, category)
559      {
560         E_Config_Theme *theme, *newtheme = NULL;
561
562         /* Not interested in adding "base" */
563         if (strcmp(category, "base"))
564           {
565              newtheme = (E_Config_Theme *)malloc(sizeof(E_Config_Theme));
566              if (!newtheme) break;
567              if (!strcmp(category, "base/theme"))
568                newtheme->category = eina_stringshare_add("base/theme/Base Theme");
569              else
570                newtheme->category = eina_stringshare_ref(category);
571              newtheme->file = NULL;
572
573              EINA_LIST_FOREACH(e_config->themes, themes, theme)
574                {
575                   if (!strcmp(category + 5, theme->category))
576                     {
577                        newtheme->file = eina_stringshare_add(theme->file);
578                     }
579                }
580              tcl = eina_list_append(tcl, newtheme);
581           }
582         eina_stringshare_del(category);
583      }
584
585    return tcl;
586 }
587
588 static const char *
589 _files_ilist_nth_label_to_file(void *data, int n)
590 {
591    E_Config_Dialog_Data *cfdata;
592    char file[1024];
593
594    if (!(cfdata = data)) return NULL;
595    if (!cfdata->o_files_ilist) return NULL;
596
597    if (n > cfdata->personal_file_count)
598      e_prefix_data_snprintf(file, sizeof(file), "data/themes/%s.edj",
599               e_widget_ilist_nth_label_get(cfdata->o_files_ilist, n));
600    else
601      e_user_dir_snprintf(file, sizeof(file), "themes/%s.edj",
602               e_widget_ilist_nth_label_get(cfdata->o_files_ilist, n));
603
604    return eina_stringshare_add(file);
605 }
606
607 static void
608 _preview_set(void *data)
609 {
610    E_Config_Dialog_Data *cfdata;
611    const char *theme;
612    char c_label[128];
613    int n;
614
615    if (!(cfdata = data)) return;
616
617    n = e_widget_ilist_selected_get(cfdata->o_files_ilist);
618    theme = _files_ilist_nth_label_to_file(cfdata, n);
619    snprintf(c_label, sizeof(c_label), "%s:",
620             e_widget_ilist_selected_label_get(cfdata->o_categories_ilist));
621    if (theme)
622      {
623         int ret = 0;
624         int i;
625
626         for (i = 0; parts_list[i]; i++)
627           if (strstr(parts_list[i], c_label)) break;
628
629         if (parts_list[i])
630           ret = e_widget_preview_edje_set(cfdata->o_preview, theme,
631                                           parts_list[i] + strlen(c_label));
632         if (!ret)
633           e_widget_preview_edje_set(cfdata->o_preview, theme,
634                                     "e/desktop/background");
635         eina_stringshare_del(theme);
636      }
637 }
638
639 static void
640 _cb_adv_categories_change(void *data, Evas_Object *obj __UNUSED__)
641 {
642    E_Config_Dialog_Data *cfdata;
643    const char *label = NULL;
644    const char *file = NULL;
645    char category[256];
646    Eina_List *themes = NULL;
647    E_Config_Theme *t;
648    Evas_Object *ic = NULL;
649    int n, cnt;
650
651    if (!(cfdata = data)) return;
652
653    label = e_widget_ilist_selected_label_get(cfdata->o_categories_ilist);
654    if (!label) return;
655
656    n = e_widget_ilist_selected_get(cfdata->o_categories_ilist);
657    ic = e_widget_ilist_nth_icon_get(cfdata->o_categories_ilist, n);
658    if (!ic)
659      {
660         _preview_set(data);
661         return;
662      }
663
664    snprintf(category, sizeof(category), "base/theme/%s", label);
665    EINA_LIST_FOREACH(cfdata->theme_list, themes, t)
666      {
667         if (!strcmp(category, t->category) && (t->file))
668           {
669              file = t->file;
670              break;
671           }
672      }
673    if (!file) return;
674
675    cnt = e_widget_ilist_count(cfdata->o_files_ilist);
676    for (n = 0; n < cnt; n++)
677      {
678         const char *tmp;
679
680         tmp = _files_ilist_nth_label_to_file(cfdata, n);
681         eina_stringshare_del(tmp);
682         if (file == tmp) /* We don't need the value, just the address. */
683           {
684              e_widget_ilist_selected_set(cfdata->o_files_ilist, n);
685              break;
686           }
687      }
688 }
689
690 static void
691 _cb_adv_theme_change(void *data, Evas_Object *obj __UNUSED__)
692 {
693    _preview_set(data);
694 }
695
696 static int
697 _theme_file_used(Eina_List *tlist, const char *filename)
698 {
699    E_Config_Theme *theme;
700    Eina_List *l;
701
702    if (!filename) return 0;
703
704    EINA_LIST_FOREACH(tlist, l, theme)
705      if (theme->file == filename) return 1;
706
707    return 0;
708 }
709
710 static void
711 _ilist_files_add(E_Config_Dialog_Data *cfdata,
712                  const char *header, const char *dir,
713                  int *count_cb)
714 {
715    Eina_Iterator *it;
716    const char *file;
717    Eina_List *themefiles = NULL;
718    int count = 0;
719    char *tmp;
720    Evas_Object *o;
721    const char *theme;
722    Evas *evas;
723
724    o = cfdata->o_files_ilist;
725    e_widget_ilist_header_append(o, NULL, header);
726    evas = evas_object_evas_get(o);
727
728    it = eina_file_ls(dir);
729
730    if (it)
731      {
732         EINA_ITERATOR_FOREACH(it, file)
733           if (strstr(file, ".edj"))
734             {
735                themefiles = eina_list_append(themefiles, file);
736             }
737           else
738             {
739                eina_stringshare_del(file);
740             }
741
742         eina_iterator_free(it);
743      }
744
745    if (themefiles)
746      {
747         char themename[PATH_MAX];
748
749         themefiles = eina_list_sort(themefiles, -1, _cb_sort);
750         count = eina_list_count(themefiles);
751
752         EINA_LIST_FREE(themefiles, theme)
753           {
754              Evas_Object *ic = NULL;
755
756              if (_theme_file_used(cfdata->theme_list, theme))
757                {
758                   ic = e_icon_add(evas);
759                   e_util_icon_theme_set(ic, "preferences-desktop-theme");
760                }
761              tmp = strdup(strrchr(theme, '/') + 1);
762              strncpy(themename, tmp, strlen(tmp) - 3);
763              themename[strlen(tmp) - 4] = '\0';
764              e_widget_ilist_append(o, ic, themename, NULL, NULL, NULL);
765              free(tmp);
766
767              eina_stringshare_del(theme);
768           }
769      }
770
771    if (count_cb)
772      *count_cb = count;
773 }
774
775 static void
776 _fill_files_ilist(E_Config_Dialog_Data *cfdata)
777 {
778    Evas *evas;
779    Evas_Object *o;
780    char theme_dir[4096];
781
782    if (!(o = cfdata->o_files_ilist)) return;
783
784    evas = evas_object_evas_get(o);
785    evas_event_freeze(evas);
786    edje_freeze();
787    e_widget_ilist_freeze(o);
788    e_widget_ilist_clear(o);
789
790    /* Grab the "Personal" themes. */
791    e_user_dir_concat_static(theme_dir, "themes");
792    _ilist_files_add(cfdata, _("Personal"), theme_dir, &cfdata->personal_file_count);
793
794    /* Grab the "System" themes. */
795    e_prefix_data_concat_static(theme_dir, "data/themes");
796    _ilist_files_add(cfdata, _("System"), theme_dir, NULL);
797
798    e_widget_ilist_go(o);
799    e_widget_ilist_thaw(o);
800    edje_thaw();
801    evas_event_thaw(evas);
802 }
803
804 static void
805 _fill_categories_ilist(E_Config_Dialog_Data *cfdata)
806 {
807    Evas *evas;
808    Eina_List *themes;
809    E_Config_Theme *theme;
810    Evas_Object *o;
811
812    if (!(o = cfdata->o_categories_ilist)) return;
813
814    evas = evas_object_evas_get(o);
815    evas_event_freeze(evas);
816    edje_freeze();
817    e_widget_ilist_freeze(o);
818    e_widget_ilist_clear(o);
819
820    EINA_LIST_FOREACH(cfdata->theme_list, themes, theme)
821      {
822         Evas_Object *ic = NULL;
823
824         if (theme->file)
825           {
826              ic = e_icon_add(evas);
827              e_util_icon_theme_set(ic, "dialog-ok-apply");
828           }
829         e_widget_ilist_append(o, ic, theme->category + 11, NULL, NULL, NULL);
830      }
831
832    e_widget_ilist_go(o);
833    e_widget_ilist_thaw(o);
834    edje_thaw();
835    evas_event_thaw(evas);
836 }
837
838 static void
839 _cb_adv_btn_assign(void *data1, void *data2 __UNUSED__)
840 {
841    Evas *evas;
842    E_Config_Dialog_Data *cfdata;
843    E_Config_Theme *newtheme, *t;
844    Eina_List *themes;
845    Evas_Object *ic = NULL, *oc = NULL, *of = NULL;
846    char buf[1024];
847    const char *label;
848    int n, cnt;
849
850    if (!(cfdata = data1)) return;
851
852    if (!(oc = cfdata->o_categories_ilist)) return;
853    if (!(of = cfdata->o_files_ilist)) return;
854
855    evas = evas_object_evas_get(oc);
856    n = e_widget_ilist_selected_get(oc);
857    ic = e_icon_add(evas);
858    e_util_icon_theme_set(ic, "enlightenment");
859    e_widget_ilist_nth_icon_set(oc, n, ic);
860
861    newtheme = malloc(sizeof(E_Config_Theme));
862    if (!newtheme) return;
863
864    label = e_widget_ilist_selected_label_get(oc);
865    snprintf(buf, sizeof(buf), "base/theme/%s", label);
866    newtheme->category = eina_stringshare_add(buf);
867
868    n = e_widget_ilist_selected_get(of);
869    ic = e_icon_add(evas);
870    e_util_icon_theme_set(ic, "preferences-desktop-theme");
871    e_widget_ilist_nth_icon_set(of, n, ic);
872    newtheme->file = _files_ilist_nth_label_to_file(cfdata, n);
873
874    EINA_LIST_FOREACH(cfdata->theme_list, themes, t)
875      {
876         const char *filename = NULL;
877
878         if (!strcmp(t->category, newtheme->category))
879           {
880              if ((t->file) && (strcmp(t->file, newtheme->file)))
881                {
882                   filename = t->file;
883                   t->file = NULL;
884
885                   if (!_theme_file_used(cfdata->theme_list, filename))
886                     {
887                        cnt = e_widget_ilist_count(of);
888                        for (n = 0; n < cnt; n++)
889                          {
890                             const char *tmp;
891
892                             tmp = _files_ilist_nth_label_to_file(cfdata, n);
893                             eina_stringshare_del(tmp);
894                             if (filename == tmp) /* We just need the pointer, not the value. */
895                               e_widget_ilist_nth_icon_set(of, n, NULL);
896                          }
897                     }
898                }
899              t->file = eina_stringshare_add(newtheme->file);
900              if (filename) eina_stringshare_del(filename);
901              break;
902           }
903      }
904    if (!themes)
905      cfdata->theme_list = eina_list_append(cfdata->theme_list, newtheme);
906    else
907      {
908         eina_stringshare_del(newtheme->category);
909         eina_stringshare_del(newtheme->file);
910         free(newtheme);
911      }
912
913    return;
914 }
915
916 static void
917 _cb_adv_btn_clear(void *data1, void *data2 __UNUSED__)
918 {
919    E_Config_Dialog_Data *cfdata;
920    E_Config_Theme *t;
921    Eina_List *themes;
922    Evas_Object *oc = NULL, *of = NULL;
923    char cat[1024];
924    const char *label;
925    const char *filename = NULL;
926    int n, cnt;
927
928    if (!(cfdata = data1)) return;
929
930    if (!(oc = cfdata->o_categories_ilist)) return;
931    if (!(of = cfdata->o_files_ilist)) return;
932
933    n = e_widget_ilist_selected_get(oc);
934    e_widget_ilist_nth_icon_set(oc, n, NULL);
935
936    label = e_widget_ilist_selected_label_get(oc);
937    snprintf(cat, sizeof(cat), "base/theme/%s", label);
938
939    EINA_LIST_FOREACH(cfdata->theme_list, themes, t)
940      {
941         if (!strcmp(t->category, cat))
942           {
943              if (t->file)
944                {
945                   filename = t->file;
946                   t->file = NULL;
947                }
948              break;
949           }
950      }
951
952    if ((filename) && (!_theme_file_used(cfdata->theme_list, filename)))
953      {
954         cnt = e_widget_ilist_count(of);
955         for (n = 0; n < cnt; n++)
956           {
957              const char *tmp;
958
959              tmp = _files_ilist_nth_label_to_file(cfdata, n);
960              if (filename == tmp)
961                e_widget_ilist_nth_icon_set(of, n, NULL);
962              eina_stringshare_del(tmp);
963           }
964         eina_stringshare_del(filename);
965      }
966
967    return;
968 }
969
970 static void
971 _cb_adv_btn_clearall(void *data1, void *data2 __UNUSED__)
972 {
973    E_Config_Dialog_Data *cfdata;
974    E_Config_Theme *t;
975    Eina_List *themes;
976    Evas_Object *oc = NULL, *of = NULL;
977    int n, cnt;
978
979    if (!(cfdata = data1)) return;
980
981    if (!(oc = cfdata->o_categories_ilist)) return;
982    if (!(of = cfdata->o_files_ilist)) return;
983
984    cnt = e_widget_ilist_count(oc);
985    for (n = 0; n < cnt; n++)
986      e_widget_ilist_nth_icon_set(oc, n, NULL);
987
988    cnt = e_widget_ilist_count(of);
989    for (n = 0; n < cnt; n++)
990      e_widget_ilist_nth_icon_set(of, n, NULL);
991
992    EINA_LIST_FOREACH(cfdata->theme_list, themes, t)
993      {
994         eina_stringshare_del(t->file);
995         t->file = NULL;
996      }
997
998    return;
999 }
1000
1001 static Evas_Object *
1002 _advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
1003 {
1004    Evas_Object *ot, *of, *ob, *oa, *ol;
1005    int mw, mh;
1006    E_Zone *zone;
1007
1008    zone = e_zone_current_get(cfd->con);
1009    ot = e_widget_table_add(evas, 0);
1010
1011    of = e_widget_framelist_add(evas, _("Theme Categories"), 0);
1012    ob = e_widget_ilist_add(evas, 16, 16, NULL);
1013    e_widget_on_change_hook_set(ob, _cb_adv_categories_change, cfdata);
1014    cfdata->o_categories_ilist = ob;
1015    e_widget_ilist_multi_select_set(ob, 0);
1016    e_widget_size_min_set(ob, 150, 250);
1017    e_widget_framelist_object_append(of, ob);
1018    e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 0, 1);
1019
1020    of = e_widget_framelist_add(evas, _("Themes"), 0);
1021    ob = e_widget_ilist_add(evas, 16, 16, NULL);
1022    e_widget_on_change_hook_set(ob, _cb_adv_theme_change, cfdata);
1023    cfdata->o_files_ilist = ob;
1024    e_widget_size_min_set(ob, 150, 250);
1025    e_widget_framelist_object_append(of, ob);
1026    e_widget_table_object_append(ot, of, 1, 0, 1, 1, 1, 1, 1, 1);
1027
1028    ol = e_widget_list_add(evas, 1, 1);
1029    ob = e_widget_button_add(evas, _("Assign"), NULL,
1030                             _cb_adv_btn_assign, cfdata, NULL);
1031    e_widget_list_object_append(ol, ob, 1, 0, 0.5);
1032    ob = e_widget_button_add(evas, _("Clear"), NULL,
1033                             _cb_adv_btn_clear, cfdata, NULL);
1034    e_widget_list_object_append(ol, ob, 1, 0, 0.5);
1035    ob = e_widget_button_add(evas, _("Clear All"), NULL,
1036                             _cb_adv_btn_clearall, cfdata, NULL);
1037    e_widget_list_object_append(ol, ob, 1, 0, 0.5);
1038    e_widget_table_object_append(ot, ol, 0, 1, 1, 1, 1, 0, 0, 0);
1039
1040    of = e_widget_framelist_add(evas, _("Preview"), 0);
1041    mw = 320;
1042    mh = (mw * zone->h) / zone->w;
1043    oa = e_widget_aspect_add(evas, mw, mh);
1044    ob = e_widget_preview_add(evas, mw, mh);
1045    cfdata->o_preview = ob;
1046    if (cfdata->theme)
1047      e_widget_preview_edje_set(ob, cfdata->theme, "e/desktop/background");
1048    e_widget_aspect_child_set(oa, ob);
1049    e_widget_framelist_object_append(of, oa);
1050    e_widget_table_object_append(ot, of, 2, 0, 1, 1, 1, 1, 1, 1);
1051
1052    _fill_files_ilist(cfdata);
1053    _fill_categories_ilist(cfdata);
1054
1055    e_widget_ilist_selected_set(cfdata->o_files_ilist, 1);
1056    e_widget_ilist_selected_set(cfdata->o_categories_ilist, 0);
1057
1058    /* FIXME this makes the preview disappear at the beginning and
1059       when resizing (Issue is caused by e_widget_aspect i guess) */
1060    // e_dialog_resizable_set(cfd->dia, 1);
1061    return ot;
1062 }
1063
1064 static int
1065 _advanced_apply_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
1066 {
1067    E_Config_Theme *theme;
1068    Eina_List *themes;
1069    E_Action *a;
1070
1071    EINA_LIST_FOREACH(cfdata->theme_list, themes, theme)
1072      {
1073         E_Config_Theme *ec_theme;
1074         Eina_List *ec_themes;
1075
1076         if (!strcmp(theme->category, "base/theme/Base Theme"))
1077           theme->category = eina_stringshare_add("base/theme");
1078
1079         EINA_LIST_FOREACH(e_config->themes, ec_themes, ec_theme)
1080           {
1081              if (!strcmp(theme->category + 5, ec_theme->category))
1082                {
1083                   if (theme->file)
1084                     e_theme_config_set(theme->category + 5, theme->file);
1085                   else
1086                     e_theme_config_remove(theme->category + 5);
1087                   break;
1088                }
1089           }
1090         if ((!ec_themes) && (theme->file))
1091           e_theme_config_set(theme->category + 5, theme->file);
1092      }
1093
1094    e_config_save_queue();
1095
1096    a = e_action_find("restart");
1097    if ((a) && (a->func.go)) a->func.go(NULL, NULL);
1098
1099    return 1;
1100 }