fedfdbd49e8f033e530bec626025cdda0c315cbd
[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
319         if (!eina_list_data_find(system_desktops, desktop)) continue;
320         cfg_cat = NULL;
321         cfg_icon = NULL;
322         cfg_cat_cfg = NULL;
323         cfg_pri = 1000;
324         cfg_cat_name = NULL;
325         cfg_cat_icon = NULL;
326         label = NULL;
327         if (desktop->x)
328           {
329              cfg_cat_cfg = eina_hash_find(desktop->x, "X-Enlightenment-Config-Category");
330              s = eina_hash_find(desktop->x, "X-Enlightenment-Config-Priority");
331              if (s) cfg_pri = atoi(s);
332              cfg_cat_name = eina_hash_find(desktop->x, "X-Enlightenment-Config-Category-Name");
333              cfg_cat_icon = eina_hash_find(desktop->x, "X-Enlightenment-Config-Category-Icon");
334              if ((cfg_cat_icon) && (cfg_cat_icon[0] != '/'))
335                cfg_cat_icon = efreet_icon_path_find(e_config->icon_theme,
336                                                     cfg_cat_icon, 64);
337           }
338         if (desktop->icon)
339           {
340              if (desktop->icon[0] == '/')
341                cfg_icon = desktop->icon;
342              else
343                cfg_icon = efreet_icon_path_find(e_config->icon_theme,
344                                                 desktop->icon, 64);
345           }
346         if (desktop->name) label = desktop->name;
347         else if (desktop->generic_name) label = desktop->generic_name;
348         else label = "???";
349         if (!cfg_cat_cfg)
350           {
351              const char *ic;
352
353              snprintf(buf, sizeof(buf), "system/%s", label);
354              cfg_cat_cfg = buf;
355              ic = cfg_cat_icon;
356              if (!ic) ic = "system";
357              e_configure_registry_category_add("system", 1000, _("System"),
358                                                NULL, ic);
359           }
360         else
361           {
362              cfg_cat = ecore_file_dir_get(cfg_cat_cfg);
363              if (!cfg_cat) cfg_cat = strdup(cfg_cat_cfg);
364              if (cfg_cat)
365                {
366                   if (!cfg_cat_name) cfg_cat_name = cfg_cat;
367                   e_configure_registry_category_add(cfg_cat,
368                                                     1000, cfg_cat_name,
369                                                     NULL, cfg_cat_icon);
370                   free(cfg_cat);
371                   cfg_cat = NULL;
372                }
373           }
374         _e_configure_registry_item_full_add(cfg_cat_cfg, cfg_pri, label,
375                                             NULL, cfg_icon,
376                                             NULL, NULL, desktop, NULL);
377      }
378    EINA_LIST_FREE(settings_desktops, desktop)
379       efreet_desktop_free(desktop);
380    EINA_LIST_FREE(system_desktops, desktop)
381       efreet_desktop_free(desktop);
382 }
383
384 static Eina_Bool
385 _e_configure_cb_efreet_desktop_cache_update(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
386 {
387    _e_configure_efreet_desktop_cleanup();
388    if (update_job) ecore_job_del(update_job);
389    update_job = ecore_job_add(_configure_job, NULL);
390    return 1;
391 }
392
393 static void
394 _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)
395 {
396    Eina_List *l;
397    char *cat;
398    const char *item;
399    E_Configure_It *eci;
400    E_Configure_Cat *ecat;
401
402    /* path is "category/item" */
403    cat = ecore_file_dir_get(path);
404    if (!cat) return;
405    item = ecore_file_file_get(path);
406    eci = E_NEW(E_Configure_It, 1);
407    if (!eci) goto done;
408
409    eci->item = eina_stringshare_add(item);
410    eci->pri = pri;
411    eci->label = eina_stringshare_add(label);
412    if (icon_file) eci->icon_file = eina_stringshare_add(icon_file);
413    if (icon) eci->icon = eina_stringshare_add(icon);
414    if (params) eci->params = eina_stringshare_add(params);
415    eci->func = func;
416    eci->generic_func = generic_func;
417    eci->desktop = desktop;
418    if (eci->desktop) efreet_desktop_ref(eci->desktop);
419
420    EINA_LIST_FOREACH(e_configure_registry, l, ecat)
421      if (!strcmp(cat, ecat->cat))
422        {
423           E_Configure_It *eci2;
424           Eina_List *ll;
425
426           EINA_LIST_FOREACH(ecat->items, ll, eci2)
427             if (eci2->pri > eci->pri)
428               {
429                  ecat->items = eina_list_prepend_relative_list(ecat->items, eci, ll);
430                  goto done;
431               }
432           ecat->items = eina_list_append(ecat->items, eci);
433           goto done;
434        }
435
436  done:
437    free(cat);
438 }
439
440 static void
441 _e_configure_registry_item_free(E_Configure_It *eci)
442 {
443    eina_stringshare_del(eci->item);
444    eina_stringshare_del(eci->label);
445    eina_stringshare_del(eci->icon);
446    if (eci->icon_file) eina_stringshare_del(eci->icon_file);
447    if (eci->desktop) efreet_desktop_free(eci->desktop);
448    if (eci->params) eina_stringshare_del(eci->params);
449    free(eci);
450 }