update for beta release
[framework/uifw/e17.git] / src / bin / e_configure.c
1 #include "e.h"
2
3 static void _e_configure_menu_module_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
4 static void _e_configure_menu_add(void *data, E_Menu *m);
5 static void _e_configure_efreet_desktop_cleanup(void);
6 static void _e_configure_efreet_desktop_update(void);
7 static Eina_Bool _e_configure_cb_efreet_desktop_cache_update(void *data, int type, void *event);
8 static void _e_configure_registry_item_full_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon, E_Config_Dialog *(*func) (E_Container *con, const char *params), void (*generic_func) (E_Container *con, const char *params), Efreet_Desktop *desktop, const char *params);
9 static void _e_configure_registry_item_free(E_Configure_It *eci);
10
11 static void _configure_job(void *data);
12 static Eina_Bool _configure_init_timer(void *data);
13
14 EAPI Eina_List *e_configure_registry = NULL;
15
16 static Eina_List *handlers = NULL;
17 static E_Int_Menu_Augmentation *maug = NULL;
18 static Ecore_Job *update_job = NULL;
19
20 static struct {
21    void (*func) (const void *data, E_Container *con, const char *params, Efreet_Desktop *desktop);
22    const char *data;
23 } custom_desktop_exec = { NULL, NULL };
24
25 EINTERN void
26 e_configure_init(void)
27 {
28    e_configure_registry_category_add("extensions", 90, _("Extensions"), NULL, "preferences-extensions");
29    e_configure_registry_item_add("extensions/modules", 10, _("Modules"), NULL, "preferences-plugin", e_int_config_modules);
30
31    maug = e_int_menus_menu_augmentation_add_sorted
32      ("config/1", _("Modules"), _e_configure_menu_add, NULL, NULL, NULL);
33
34    if (update_job)
35       {
36          ecore_job_del(update_job);
37          update_job = NULL;
38       }
39    ecore_timer_add(0.0, _configure_init_timer, NULL);
40 }
41
42 EAPI void
43 e_configure_registry_call(const char *path, E_Container *con, const char *params)
44 {
45    E_Configure_Cat *ecat;
46    Eina_List *l;
47    char *cat;
48    const char *item;
49
50    /* path is "category/item" */
51    cat = ecore_file_dir_get(path);
52    if (!cat) return;
53    item = ecore_file_file_get(path);
54    EINA_LIST_FOREACH(e_configure_registry, l, ecat)
55      if (!strcmp(cat, ecat->cat))
56        {
57           E_Configure_It *eci;
58           Eina_List *ll;
59
60           EINA_LIST_FOREACH(ecat->items, ll, eci)
61             if (!strcmp(item, eci->item))
62               {
63                  if (!params) params = eci->params;
64                  
65                  if (eci->func) eci->func(con, params);
66                  else if (eci->generic_func) eci->generic_func(con, params);
67                  else if (eci->desktop)
68                    {
69                       if (custom_desktop_exec.func)
70                         custom_desktop_exec.func(custom_desktop_exec.data,
71                                                  con, params, eci->desktop);
72                       else
73                         e_exec(e_util_zone_current_get(con->manager),
74                                eci->desktop, NULL, NULL, "config");
75                    }
76                  break;
77               }
78           break;
79        }
80    free(cat);
81 }
82
83 EAPI void
84 e_configure_registry_item_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon, E_Config_Dialog *(*func) (E_Container *con, const char *params))
85 {
86    _e_configure_registry_item_full_add(path, pri, label, icon_file, icon, func, NULL, NULL, NULL);
87 }
88
89 EAPI void
90 e_configure_registry_generic_item_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon, void (*generic_func) (E_Container *con, const char *params))
91 {
92    _e_configure_registry_item_full_add(path, pri, label, icon_file, icon, NULL, generic_func, NULL, NULL);
93 }
94
95 EAPI void
96 e_configure_registry_item_params_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon, E_Config_Dialog *(*func) (E_Container *con, const char *params), const char *params)
97 {
98    _e_configure_registry_item_full_add(path, pri, label, icon_file, icon, func, NULL, NULL, params);
99 }
100
101 EAPI void
102 e_configure_registry_item_del(const char *path)
103 {
104    E_Configure_Cat *ecat;
105    Eina_List *l;
106    const char *item;
107    char *cat;
108
109    /* path is "category/item" */
110    cat = ecore_file_dir_get(path);
111    if (!cat) return;
112    item = ecore_file_file_get(path);
113
114    EINA_LIST_FOREACH(e_configure_registry, l, ecat)
115      if (!strcmp(cat, ecat->cat))
116        {
117           E_Configure_It *eci;
118           Eina_List *ll;
119
120           EINA_LIST_FOREACH(ecat->items, ll, eci)
121             if (!strcmp(item, eci->item))
122               {
123                  ecat->items = eina_list_remove_list(ecat->items, ll);
124
125                  _e_configure_registry_item_free(eci);
126                  break;
127               }
128           break;
129        }
130    free(cat);
131 }
132
133 EAPI void
134 e_configure_registry_category_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon)
135 {
136    E_Configure_Cat *ecat2;
137    E_Configure_Cat *ecat;
138    Eina_List *l;
139
140    /* if it exists - ignore this */
141    EINA_LIST_FOREACH(e_configure_registry, l, ecat2)
142      if (!strcmp(ecat2->cat, path)) return;
143
144    ecat = E_NEW(E_Configure_Cat, 1);
145    if (!ecat) return;
146
147    ecat->cat = eina_stringshare_add(path);
148    ecat->pri = pri;
149    ecat->label = eina_stringshare_add(label);
150    if (icon_file) ecat->icon_file = eina_stringshare_add(icon_file);
151    if (icon) ecat->icon = eina_stringshare_add(icon);
152    EINA_LIST_FOREACH(e_configure_registry, l, ecat2)
153      if (ecat2->pri > ecat->pri)
154        {
155           e_configure_registry = 
156             eina_list_prepend_relative_list(e_configure_registry, ecat, l);
157           return;
158        }
159    e_configure_registry = eina_list_append(e_configure_registry, ecat);
160 }
161
162 EAPI void
163 e_configure_registry_category_del(const char *path)
164 {
165    E_Configure_Cat *ecat;
166    Eina_List *l;
167    char *cat;
168
169    cat = ecore_file_dir_get(path);
170    if (!cat) return;
171    EINA_LIST_FOREACH(e_configure_registry, l, ecat)
172      if (!strcmp(cat, ecat->cat))
173        {
174           if (ecat->items) break;
175           e_configure_registry = eina_list_remove_list(e_configure_registry, l);
176           eina_stringshare_del(ecat->cat);
177           eina_stringshare_del(ecat->label);
178           if (ecat->icon) eina_stringshare_del(ecat->icon);
179           if (ecat->icon_file) eina_stringshare_del(ecat->icon_file);
180           free(ecat);
181           break;
182        }
183    free(cat);
184 }
185
186 EAPI void
187 e_configure_registry_custom_desktop_exec_callback_set(void (*func) (const void *data, E_Container *con, const char *params, Efreet_Desktop *desktop), const void *data)
188 {
189    custom_desktop_exec.func = func;
190    custom_desktop_exec.data = data;
191 }
192
193 EAPI int
194 e_configure_registry_exists(const char *path)
195 {
196    E_Configure_Cat *ecat;
197    Eina_List *l;
198    char *cat;
199    const char *item;
200    int ret = 0;
201
202    /* path is "category/item" */
203    cat = ecore_file_dir_get(path);
204    if (!cat) return 0;
205    item = ecore_file_file_get(path);
206    EINA_LIST_FOREACH(e_configure_registry, l, ecat)
207      if (!strcmp(cat, ecat->cat))
208        {
209           E_Configure_It *eci;
210           Eina_List *ll;
211
212           if (!item)
213             {
214                ret = 1;
215                break;
216             }
217           EINA_LIST_FOREACH(ecat->items, ll, eci)
218             if (!strcmp(item, eci->item))
219               {
220                  ret = 1;
221                  break;
222               }
223           break;
224        }
225
226    free(cat);
227    return ret;
228 }
229
230 static void
231 _e_configure_menu_module_item_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
232 {
233    e_int_config_modules(m->zone->container, NULL);
234 }
235
236 static void
237 _e_configure_menu_add(void *data __UNUSED__, E_Menu *m)
238 {
239    E_Menu_Item *mi;
240
241    mi = e_menu_item_new(m);
242    e_menu_item_label_set(mi, _("Modules"));
243    e_util_menu_item_theme_icon_set(mi, "preferences-plugin");
244    e_menu_item_callback_set(mi, _e_configure_menu_module_item_cb, NULL);
245 }
246
247 static void
248 _configure_job(void *data __UNUSED__)
249 {
250    _e_configure_efreet_desktop_update();
251    update_job = NULL;
252 }
253
254 static Eina_Bool
255 _configure_init_timer(void *data __UNUSED__)
256 {
257    handlers = eina_list_append
258      (handlers, ecore_event_handler_add
259          (EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_configure_cb_efreet_desktop_cache_update, NULL));
260    if (update_job) ecore_job_del(update_job);
261    update_job = ecore_job_add(_configure_job, NULL);
262    return EINA_FALSE;
263 }
264
265 static void
266 _e_configure_efreet_desktop_cleanup(void)
267 {
268    Eina_List *l;
269    E_Configure_Cat *ecat;
270
271 //   printf("_e_configure_efreet_desktop_cleanup\n");
272    /* remove anything with a desktop entry */
273    EINA_LIST_FOREACH(e_configure_registry, l, ecat)
274      {
275         E_Configure_It *eci;
276         Eina_List *ll, *ln;
277
278         EINA_LIST_FOREACH_SAFE(ecat->items, ll, ln, eci)
279            if (eci->desktop)
280              {
281                 _e_configure_registry_item_free(eci);
282                 ecat->items = eina_list_remove_list(ecat->items, ll);
283              }
284      }
285 }
286
287 static void
288 _e_configure_efreet_desktop_update(void)
289 {
290    Eina_List *settings_desktops, *system_desktops;
291    Efreet_Desktop *desktop;
292    Eina_List *l;
293    char buf[1024];
294
295    /* get desktops */
296    settings_desktops = efreet_util_desktop_category_list("Settings");
297    system_desktops = efreet_util_desktop_category_list("System");
298    if ((!settings_desktops) && (!system_desktops))
299      {
300         EINA_LIST_FREE(settings_desktops, desktop)
301            efreet_desktop_free(desktop);
302         EINA_LIST_FREE(system_desktops, desktop)
303            efreet_desktop_free(desktop);
304         return;
305      }
306
307    /* get ones in BOTH lists */
308    EINA_LIST_FOREACH(settings_desktops, l, desktop)
309      {
310         char *s;
311         char *cfg_cat_name;
312         const char *cfg_cat_icon;
313         char *cfg_cat;
314         char *cfg_cat_cfg;
315         const char *cfg_icon;
316         char *label;
317         int cfg_pri;
318         int dopref;
319         
320         dopref = 0;
321         cfg_cat = NULL;
322         cfg_icon = NULL;
323         cfg_cat_cfg = NULL;
324         cfg_pri = 1000;
325         cfg_cat_name = NULL;
326         cfg_cat_icon = NULL;
327         label = NULL;
328         if (!eina_list_data_find(system_desktops, desktop))
329           {
330              /* settings desktop but not in system -> put in preferences */
331              dopref = 1;
332           }
333         if (desktop->x)
334           {
335              cfg_cat_cfg = eina_hash_find(desktop->x, "X-Enlightenment-Config-Category");
336              s = eina_hash_find(desktop->x, "X-Enlightenment-Config-Priority");
337              if (s) cfg_pri = atoi(s);
338              cfg_cat_name = eina_hash_find(desktop->x, "X-Enlightenment-Config-Category-Name");
339              cfg_cat_icon = eina_hash_find(desktop->x, "X-Enlightenment-Config-Category-Icon");
340              if ((cfg_cat_icon) && (cfg_cat_icon[0] != '/'))
341                cfg_cat_icon = efreet_icon_path_find(e_config->icon_theme,
342                                                     cfg_cat_icon, 64);
343           }
344         if (desktop->icon)
345           {
346              if (desktop->icon[0] == '/')
347                cfg_icon = desktop->icon;
348              else
349                cfg_icon = efreet_icon_path_find(e_config->icon_theme,
350                                                 desktop->icon, 64);
351           }
352         if (desktop->name) label = desktop->name;
353         else if (desktop->generic_name) label = desktop->generic_name;
354         else label = "???";
355         if (!cfg_cat_cfg)
356           {
357              const char *ic = cfg_cat_icon;
358              
359              if (dopref)
360                {
361                   snprintf(buf, sizeof(buf), "preferences/%s", label);
362                   if (!ic) ic = "preferences-preferences";
363                   e_configure_registry_category_add("preferences", 900,
364                                                     _("Preferences"),
365                                                     NULL, ic);
366                }
367              else
368                {
369                   snprintf(buf, sizeof(buf), "system/%s", label);
370                   if (!ic) ic = "preferences-system";
371                   e_configure_registry_category_add("system", 1000, 
372                                                     _("System"),
373                                                     NULL, ic);
374                }
375              cfg_cat_cfg = buf;
376           }
377         else
378           {
379              cfg_cat = ecore_file_dir_get(cfg_cat_cfg);
380              if (!cfg_cat) cfg_cat = strdup(cfg_cat_cfg);
381              if (cfg_cat)
382                {
383                   if (!cfg_cat_name) cfg_cat_name = cfg_cat;
384                   e_configure_registry_category_add(cfg_cat,
385                                                     1000, cfg_cat_name,
386                                                     NULL, cfg_cat_icon);
387                   free(cfg_cat);
388                   cfg_cat = NULL;
389                }
390           }
391         _e_configure_registry_item_full_add(cfg_cat_cfg, cfg_pri, label,
392                                             NULL, cfg_icon,
393                                             NULL, NULL, desktop, NULL);
394      }
395    EINA_LIST_FREE(settings_desktops, desktop)
396       efreet_desktop_free(desktop);
397    EINA_LIST_FREE(system_desktops, desktop)
398       efreet_desktop_free(desktop);
399 }
400
401 static Eina_Bool
402 _e_configure_cb_efreet_desktop_cache_update(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
403 {
404    _e_configure_efreet_desktop_cleanup();
405    if (update_job) ecore_job_del(update_job);
406    update_job = ecore_job_add(_configure_job, NULL);
407    return 1;
408 }
409
410 static void
411 _e_configure_registry_item_full_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon, E_Config_Dialog *(*func) (E_Container *con, const char *params), void (*generic_func) (E_Container *con, const char *params), Efreet_Desktop *desktop, const char *params)
412 {
413    Eina_List *l;
414    char *cat;
415    const char *item;
416    E_Configure_It *eci;
417    E_Configure_Cat *ecat;
418
419    /* path is "category/item" */
420    cat = ecore_file_dir_get(path);
421    if (!cat) return;
422    item = ecore_file_file_get(path);
423    eci = E_NEW(E_Configure_It, 1);
424    if (!eci) goto done;
425
426    eci->item = eina_stringshare_add(item);
427    eci->pri = pri;
428    eci->label = eina_stringshare_add(label);
429    if (icon_file) eci->icon_file = eina_stringshare_add(icon_file);
430    if (icon) eci->icon = eina_stringshare_add(icon);
431    if (params) eci->params = eina_stringshare_add(params);
432    eci->func = func;
433    eci->generic_func = generic_func;
434    eci->desktop = desktop;
435    if (eci->desktop) efreet_desktop_ref(eci->desktop);
436
437    EINA_LIST_FOREACH(e_configure_registry, l, ecat)
438      if (!strcmp(cat, ecat->cat))
439        {
440           E_Configure_It *eci2;
441           Eina_List *ll;
442
443           EINA_LIST_FOREACH(ecat->items, ll, eci2)
444             if (eci2->pri > eci->pri)
445               {
446                  ecat->items = eina_list_prepend_relative_list(ecat->items, eci, ll);
447                  goto done;
448               }
449           ecat->items = eina_list_append(ecat->items, eci);
450           goto done;
451        }
452
453  done:
454    free(cat);
455 }
456
457 static void
458 _e_configure_registry_item_free(E_Configure_It *eci)
459 {
460    eina_stringshare_del(eci->item);
461    eina_stringshare_del(eci->label);
462    eina_stringshare_del(eci->icon);
463    if (eci->icon_file) eina_stringshare_del(eci->icon_file);
464    if (eci->desktop) efreet_desktop_free(eci->desktop);
465    if (eci->params) eina_stringshare_del(eci->params);
466    free(eci);
467 }