1 #include "e.h"
2 #include <assert.h>
3
4 typedef struct _CFModule CFModule;
5 typedef struct _CFType CFType;
6 typedef struct _CFTypes CFTypes;
7
8 struct _CFModule
9 {
10 const char *short_name, *name, *comment;
11 const char *icon, *orig_path;
12 E_Module *module;
13 Evas_Object *end;
14 int idx;
15 Eina_Bool enabled E_BITFIELD;
16 };
17
18 struct _CFType
19 {
20 const char *key, *name, *icon;
21 Eina_Hash *modules_hash; /* just used before constructing list */
22 Eina_List *modules; /* sorted and ready to be used */
23 };
24
25 struct _E_Config_Dialog_Data
26 {
27 Evas *evas;
28 Evas_Object *l_modules;
29 Evas_Object *o_toolbar;
30 Evas_Object *b_load, *b_unload;
31 Evas_Object *o_desc;
32 Eina_List *types;
33 Ecore_Event_Handler *module_update;
34 struct
35 {
36 Eina_List *loaded, *unloaded;
37 } selected;
38 };
39
40 struct _CFTypes
41 {
42 size_t key_len;
43 const char *key, *name, *icon;
44 };
45
46 /* pre defined types (used to specify icon and i18n name) */
47 static const CFTypes _types[] =
48 {
49 #define _CFT(k, n, i) \
50 {sizeof(k) - 1, k, n, i}
51 _CFT("utils", N_("Utilities"), "modules-utils"),
52 _CFT("system", N_("System"), "modules-system"),
53 _CFT("look", N_("Look"), "modules-look"),
54 _CFT("files", N_("Files"), "modules-files"),
55 _CFT("launcher", N_("Launcher"), "modules-launcher"),
56 _CFT("core", N_("Core"), "modules-core"),
57 _CFT("mobile", N_("Mobile"), "modules-mobile"),
58 _CFT("settings", N_("Settings"), "modules-settings"),
59 #undef _CFT
60 {0, NULL, NULL, NULL}
61 };
62
63 /* local function protos */
64 static void _cftype_free(CFType *cft);
65
66 static void _widget_list_selection_changed(void *data, Evas_Object *obj EINA_UNUSED);
67
68 static void *_create_data(E_Config_Dialog *cfd);
69 static void _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
70 static Evas_Object *_basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
71 static void _fill_cat_list(E_Config_Dialog_Data *cfdata);
72 static void _module_end_state_apply(CFModule *cfm);
73
74 static void _toolbar_select_cb(void *data, void *data2);
75
76 static CFType *_cftype_find(E_Config_Dialog_Data *cfdata, const char *key, const char *name, const char *icon);
77 static CFType *_cftype_new(const char *key, const char *name, const char *icon);
78 static void _load_module(E_Module_Desktop *md, Eina_Hash *types_hash);
79 static Eina_Bool _types_list_create_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata);
80 static int _types_list_sort(const void *data1, const void *data2);
81
82 static void _btn_cb_unload(void *data, void *data2);
83 static void _btn_cb_load(void *data, void *data2);
84
85 E_API E_Config_Dialog *
e_int_config_modules(Evas_Object * parent EINA_UNUSED,const char * params EINA_UNUSED)86 e_int_config_modules(Evas_Object *parent EINA_UNUSED, const char *params EINA_UNUSED)
87 {
88 E_Config_Dialog *cfd = NULL;
89 E_Config_Dialog_View *v = NULL;
90
91 if (e_config_dialog_find("E", "extensions/modules")) return NULL;
92
93 v = E_NEW(E_Config_Dialog_View, 1);
94 v->create_cfdata = _create_data;
95 v->free_cfdata = _free_data;
96 v->basic.create_widgets = _basic_create;
97
98 cfd = e_config_dialog_new(NULL, _("Module Settings"),
99 "E", "extensions/modules",
100 "preferences-plugin", 0, v, NULL);
101 return cfd;
102 }
103
104 static void *
_create_data(E_Config_Dialog * cfd EINA_UNUSED)105 _create_data(E_Config_Dialog *cfd EINA_UNUSED)
106 {
107 Eina_Hash *types_hash;
108 Eina_List *mods;
109 E_Module_Desktop *md;
110 E_Config_Dialog_Data *cfdata;
111
112 cfdata = E_NEW(E_Config_Dialog_Data, 1);
113
114 types_hash = eina_hash_string_superfast_new(NULL);
115 mods = e_module_desktop_list();
116 if (!mods)
117 {
118 eina_hash_free(types_hash);
119 return cfdata;
120 }
121
122 EINA_LIST_FREE(mods, md)
123 {
124 _load_module(md, types_hash);
125 e_module_desktop_free(md);
126 }
127
128 eina_hash_foreach(types_hash, _types_list_create_foreach_cb, cfdata);
129 eina_hash_free(types_hash);
130 cfdata->types = eina_list_sort(cfdata->types, -1, _types_list_sort);
131
132 return cfdata;
133 }
134
135 static void
_free_data(E_Config_Dialog * cfd EINA_UNUSED,E_Config_Dialog_Data * cfdata)136 _free_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
137 {
138 CFType *cft;
139
140 EINA_LIST_FREE(cfdata->types, cft)
141 _cftype_free(cft);
142
143 eina_list_free(cfdata->selected.loaded);
144 eina_list_free(cfdata->selected.unloaded);
145 if (cfdata->module_update) ecore_event_handler_del(cfdata->module_update);
146 free(cfdata);
147 }
148
149 static Eina_Bool
_module_update(E_Config_Dialog_Data * cfdata,int type EINA_UNUSED,E_Event_Module_Update * ev)150 _module_update(E_Config_Dialog_Data *cfdata, int type EINA_UNUSED, E_Event_Module_Update *ev)
151 {
152 CFType *cft;
153 Eina_List *l, *ll;
154 CFModule *cfm;
155
156 EINA_LIST_FOREACH(cfdata->types, l, cft)
157 {
158 EINA_LIST_FOREACH(cft->modules, ll, cfm)
159 if (cfm->short_name == ev->name)
160 {
161 cfm->enabled = ev->enabled;
162 _module_end_state_apply(cfm);
163 return ECORE_CALLBACK_RENEW;
164 }
165 }
166
167 return ECORE_CALLBACK_RENEW;
168 }
169
170 static Evas_Object *
_basic_create(E_Config_Dialog * cfd,Evas * evas,E_Config_Dialog_Data * cfdata)171 _basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
172 {
173 Evas_Coord mw, mh;
174 Evas_Object *of, *ol;
175
176 e_dialog_resizable_set(cfd->dia, 1);
177
178 cfdata->evas = evas_object_evas_get(cfd->dia->win);
179
180 of = e_widget_table_add(e_win_evas_win_get(evas), 0);
181
182 cfdata->o_toolbar = e_widget_toolbar_add(evas, 32 * e_scale, 32 * e_scale);
183 e_widget_toolbar_scrollable_set(cfdata->o_toolbar, 1);
184 _fill_cat_list(cfdata);
185 e_widget_table_object_append(of, cfdata->o_toolbar, 0, 0, 2, 1, 1, 1, 1, 0);
186
187 cfdata->l_modules = e_widget_ilist_add(evas, 32 * e_scale, 32 * e_scale, NULL);
188 e_widget_ilist_multi_select_set(cfdata->l_modules, EINA_TRUE);
189 e_widget_ilist_go(cfdata->l_modules);
190 e_widget_size_min_get(cfdata->l_modules, &mw, &mh);
191 if (mw < (200 * e_scale)) mw = 200 * e_scale;
192 if (mh < (100 * e_scale)) mh = 100 * e_scale;
193 e_widget_size_min_set(cfdata->l_modules, mw, mh);
194 e_widget_on_change_hook_set(cfdata->l_modules,
195 _widget_list_selection_changed, cfdata);
196 e_widget_table_object_append(of, cfdata->l_modules, 0, 1, 2, 1, 1, 1, 1, 1);
197
198 ol = e_widget_button_add(evas, _("Load"), NULL, _btn_cb_load, cfdata, NULL);
199 cfdata->b_load = ol;
200 e_widget_disabled_set(ol, 1);
201 e_widget_table_object_append(of, ol, 0, 2, 1, 1, 1, 1, 1, 0);
202
203 ol = e_widget_button_add(evas, _("Unload"), NULL, _btn_cb_unload, cfdata, NULL);
204 cfdata->b_unload = ol;
205 e_widget_disabled_set(ol, 1);
206 e_widget_table_object_append(of, ol, 1, 2, 1, 1, 1, 1, 1, 0);
207
208 ol = e_widget_textblock_add(evas);
209 e_widget_size_min_set(ol, (200 * e_scale), 40 * e_scale);
210 cfdata->o_desc = ol;
211 e_widget_table_object_append(of, ol, 0, 3, 2, 1, 1, 0, 1, 0);
212
213 e_dialog_resizable_set(cfd->dia, 1);
214 e_util_win_auto_resize_fill(cfd->dia->win);
215 elm_win_center(cfd->dia->win, 1, 1);
216
217 e_widget_focus_set(cfdata->o_toolbar, 1);
218 e_widget_toolbar_item_select(cfdata->o_toolbar, 0);
219
220 cfdata->module_update = ecore_event_handler_add(E_EVENT_MODULE_UPDATE, (Ecore_Event_Handler_Cb)_module_update, cfdata);
221
222 return of;
223 }
224
225 static void
_fill_cat_list(E_Config_Dialog_Data * cfdata)226 _fill_cat_list(E_Config_Dialog_Data *cfdata)
227 {
228 Evas_Coord w, h;
229 Evas_Object *icon;
230 CFType *cft;
231 const CFTypes *itr;
232
233 evas_event_freeze(cfdata->evas);
234 edje_freeze();
235
236 for (itr = _types; itr->key_len > 0; itr++)
237 {
238 cft = _cftype_find(cfdata, itr->key, itr->name, itr->icon);
239 if (!cft)
240 {
241 WRN("CFT MISSING!!! key(%s) name(%s) icon(%s)", itr->key, itr->name, itr->icon);
242 continue;
243 }
244 icon = e_icon_add(cfdata->evas);
245 if (icon)
246 {
247 if (!e_util_icon_theme_set(icon, cft->icon))
248 {
249 evas_object_del(icon);
250 icon = NULL;
251 }
252 }
253
254 e_widget_toolbar_item_append(cfdata->o_toolbar, icon, _(cft->name),
255 _toolbar_select_cb, cfdata, cft);
256 }
257
258 e_widget_size_min_get(cfdata->o_toolbar, &w, &h);
259 e_widget_size_min_set(cfdata->o_toolbar, w, h);
260
261 edje_thaw();
262 evas_event_thaw(cfdata->evas);
263 }
264
265 static void
_list_item_append(E_Config_Dialog_Data * cfdata,CFModule * cfm)266 _list_item_append(E_Config_Dialog_Data *cfdata, CFModule *cfm)
267 {
268 Evas_Object *icon, *end;
269
270 if (!cfm->icon)
271 icon = NULL;
272 else
273 {
274 icon = e_icon_add(cfdata->evas);
275 if (icon)
276 {
277 if (!e_util_icon_theme_set(icon, cfm->icon))
278 {
279 if (cfm->orig_path)
280 {
281 char *dir = ecore_file_dir_get(cfm->orig_path);
282 char buf[PATH_MAX];
283
284 snprintf(buf, sizeof(buf), "%s/%s.edj", dir, cfm->icon);
285 free(dir);
286
287 e_icon_file_edje_set(icon, buf, "icon");
288 }
289 else
290 {
291 evas_object_del(icon);
292 icon = NULL;
293 }
294 }
295 }
296 }
297
298 end = edje_object_add(cfdata->evas);
299 if (end)
300 {
301 if (e_theme_edje_object_set(end, "base/theme/widgets",
302 "e/widgets/ilist/toggle_end"))
303 {
304 cfm->end = end;
305 _module_end_state_apply(cfm);
306 }
307 else
308 {
309 EINA_LOG_ERR("your theme is missing 'e/widgets/ilist/toggle_end'!");
310 evas_object_del(end);
311 end = NULL;
312 }
313 }
314
315 e_widget_ilist_append_full(cfdata->l_modules, icon, end,
316 cfm->name, NULL, cfm, NULL);
317 }
318
319 static void
_toolbar_select_cb(void * data,void * data2)320 _toolbar_select_cb(void *data, void *data2)
321 {
322 CFType *cft, *cft_cat;
323 E_Config_Dialog_Data *cfdata;
324 Eina_List *l_type;
325 Evas_Coord w, h;
326
327 cfdata = data;
328 cft_cat = data2;
329 if (!cfdata || !cft_cat) return;
330
331 eina_list_free(cfdata->selected.loaded);
332 eina_list_free(cfdata->selected.unloaded);
333 cfdata->selected.loaded = NULL;
334 cfdata->selected.unloaded = NULL;
335 e_widget_disabled_set(cfdata->b_load, EINA_TRUE);
336 e_widget_disabled_set(cfdata->b_unload, EINA_TRUE);
337 e_widget_textblock_markup_set(cfdata->o_desc, _("No modules selected."));
338
339 evas_event_freeze(evas_object_evas_get(cfdata->l_modules));
340 edje_freeze();
341 e_widget_ilist_freeze(cfdata->l_modules);
342 e_widget_ilist_clear(cfdata->l_modules);
343
344 EINA_LIST_FOREACH(cfdata->types, l_type, cft)
345 {
346 CFModule *cfm;
347 Eina_List *l_module;
348
349 if (strcmp(cft->key, cft_cat->key))
350 continue;
351
352 EINA_LIST_FOREACH(cft->modules, l_module, cfm)
353 _list_item_append(cfdata, cfm);
354 }
355
356 e_widget_ilist_go(cfdata->l_modules);
357 e_widget_size_min_get(cfdata->l_modules, &w, &h);
358 e_widget_size_min_set(cfdata->l_modules, w, h);
359 e_widget_ilist_thaw(cfdata->l_modules);
360 edje_thaw();
361 evas_event_thaw(evas_object_evas_get(cfdata->l_modules));
362 }
363
364 static CFModule *
_module_new(const char * short_name,const Efreet_Desktop * desk)365 _module_new(const char *short_name, const Efreet_Desktop *desk)
366 {
367 CFModule *cfm = E_NEW(CFModule, 1);
368
369 if (!cfm) return NULL;
370 cfm->short_name = eina_stringshare_add(short_name);
371
372 if (desk->name)
373 cfm->name = eina_stringshare_add(desk->name);
374 else
375 cfm->name = eina_stringshare_ref(cfm->short_name);
376
377 cfm->icon = eina_stringshare_add(desk->icon);
378 cfm->comment = eina_stringshare_add(desk->comment);
379 cfm->orig_path = eina_stringshare_add(desk->orig_path);
380 return cfm;
381 }
382
383 static void
_module_free(CFModule * cfm)384 _module_free(CFModule *cfm)
385 {
386 eina_stringshare_del(cfm->short_name);
387 eina_stringshare_del(cfm->name);
388 eina_stringshare_del(cfm->icon);
389 eina_stringshare_del(cfm->comment);
390 eina_stringshare_del(cfm->orig_path);
391 E_FREE(cfm);
392 }
393
394 static void
_module_end_state_apply(CFModule * cfm)395 _module_end_state_apply(CFModule *cfm)
396 {
397 const char *sig;
398
399 if (!cfm->end) return;
400 sig = cfm->enabled ? "e,state,checked" : "e,state,unchecked";
401 edje_object_signal_emit(cfm->end, sig, "e");
402 }
403
404 static CFType *
_cftype_find(E_Config_Dialog_Data * cfdata,const char * key,const char * name,const char * icon)405 _cftype_find(E_Config_Dialog_Data *cfdata, const char *key, const char *name, const char *icon)
406 {
407 CFType *cft;
408 Eina_List *l;
409
410 EINA_LIST_FOREACH(cfdata->types, l, cft)
411 if ((!strcmp(cft->key, key)) && (!strcmp(cft->name, name)) && (!strcmp(cft->icon, icon))) return cft;
412 return NULL;
413 }
414
415 static CFType *
_cftype_new(const char * key,const char * name,const char * icon)416 _cftype_new(const char *key, const char *name, const char *icon)
417 {
418 CFType *cft = E_NEW(CFType, 1);
419
420 if (!cft) return NULL;
421 cft->key = eina_stringshare_add(key);
422 cft->name = eina_stringshare_add(name);
423 cft->icon = eina_stringshare_add(icon);
424 //INF("CFT NEW: key(%s) name(%s) icon(%s)", key, name, icon);
425 return cft;
426 }
427
428 static void
_cftype_free(CFType * cft)429 _cftype_free(CFType *cft)
430 {
431 CFModule *cfm;
432
433 assert(cft->modules_hash == NULL); // must do it before calling this function
434 EINA_LIST_FREE(cft->modules, cfm)
435 _module_free(cfm);
436
437 eina_stringshare_del(cft->key);
438 eina_stringshare_del(cft->name);
439 eina_stringshare_del(cft->icon);
440 E_FREE(cft);
441 }
442
443 static CFType *
_cftype_new_from_key(const char * key)444 _cftype_new_from_key(const char *key)
445 {
446 const CFTypes *itr;
447 char name[1024], icon[1024];
448 size_t key_len;
449
450 if (!key) return NULL;
451
452 key_len = strlen(key);
453 for (itr = _types; itr->key_len > 0; itr++)
454 {
455 if (key_len != itr->key_len) continue;
456 if (strcmp(itr->key, key) != 0) continue;
457 return _cftype_new(itr->key, itr->name, itr->icon);
458 }
459
460 if ((key_len + 1) >= sizeof(name)) return NULL;
461 if ((key_len + sizeof("enlightenment/")) >= sizeof(icon)) return NULL;
462
463 memcpy(name, key, key_len + 1);
464 name[0] = toupper(name[0]);
465
466 snprintf(icon, sizeof(icon), "enlightenment/%s", key);
467 return _cftype_new(key, name, icon);
468 }
469
470 static void
_load_module(E_Module_Desktop * md,Eina_Hash * types_hash)471 _load_module(E_Module_Desktop *md, Eina_Hash *types_hash)
472 {
473 CFType *cft;
474 CFModule *cfm;
475 const char *type, *mod;
476 Eina_Bool new_type = EINA_FALSE;
477
478 mod = ecore_file_file_get(md->dir);
479 if (md->desktop->x)
480 type = eina_hash_find(md->desktop->x, "X-Enlightenment-ModuleType");
481 else
482 type = NULL;
483 if (!type) type = "utils"; // todo: warn?
484
485 cft = eina_hash_find(types_hash, type);
486 if (cft)
487 {
488 new_type = EINA_FALSE;
489 if ((cft->modules_hash) &&
490 (eina_hash_find(cft->modules_hash, mod)))
491 return;
492 }
493 else
494 {
495 cft = _cftype_new_from_key(type);
496 if (cft) new_type = EINA_TRUE;
497 else return;
498 }
499
500 cfm = _module_new(mod, md->desktop);
501 if (!cfm)
502 {
503 if (new_type) _cftype_free(cft);
504 return;
505 }
506
507 if (!cft->modules_hash)
508 cft->modules_hash = eina_hash_string_superfast_new(NULL);
509 eina_hash_direct_add(cft->modules_hash, cfm->short_name, cfm);
510 cft->modules = eina_list_append(cft->modules, cfm);
511 cfm->module = e_module_find(mod);
512 if (cfm->module)
513 cfm->enabled = e_module_enabled_get(cfm->module);
514 else
515 cfm->enabled = 0;
516
517 if (new_type)
518 eina_hash_direct_add(types_hash, cft->key, cft);
519 }
520
521 static int
_modules_list_sort(const void * data1,const void * data2)522 _modules_list_sort(const void *data1, const void *data2)
523 {
524 const CFModule *m1 = data1, *m2 = data2;
525 return strcmp(m1->name, m2->name);
526 }
527
528 static Eina_Bool
_types_list_create_foreach_cb(const Eina_Hash * hash EINA_UNUSED,const void * key EINA_UNUSED,void * data,void * fdata)529 _types_list_create_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
530 {
531 E_Config_Dialog_Data *cfdata = fdata;
532 CFType *cft = data;
533
534 // otherwise it should not be here
535 assert(cft->modules);
536 assert(cft->modules_hash);
537
538 eina_hash_free(cft->modules_hash);
539 cft->modules_hash = NULL;
540
541 cft->modules = eina_list_sort(cft->modules, -1, _modules_list_sort);
542 cfdata->types = eina_list_append(cfdata->types, cft);
543 // TODO be paranoid about list append failure, otherwise leaks memory
544 return EINA_TRUE;
545 }
546
547 static int
_types_list_sort(const void * data1,const void * data2)548 _types_list_sort(const void *data1, const void *data2)
549 {
550 const CFType *t1 = data1, *t2 = data2;
551 return strcmp(t1->name, t2->name);
552 }
553
554 static void
_widget_list_selection_changed(void * data,Evas_Object * obj EINA_UNUSED)555 _widget_list_selection_changed(void *data, Evas_Object *obj EINA_UNUSED)
556 {
557 E_Config_Dialog_Data *cfdata = data;
558 const Eina_List *l;
559 const E_Ilist_Item *it;
560 CFModule *cfm = NULL;
561 const char *description;
562
563 cfdata->selected.loaded = eina_list_free(cfdata->selected.loaded);
564 cfdata->selected.unloaded = eina_list_free(cfdata->selected.unloaded);
565
566 EINA_LIST_FOREACH(e_widget_ilist_selected_items_get(cfdata->l_modules), l, it)
567 {
568 cfm = e_widget_ilist_item_data_get(it);
569
570 if (cfm->enabled)
571 {
572 cfdata->selected.loaded =
573 eina_list_append(cfdata->selected.loaded, cfm);
574 e_widget_disabled_set(cfdata->b_unload, 0);
575 e_widget_disabled_set(cfdata->b_load, 1);
576 }
577 else
578 {
579 cfdata->selected.unloaded =
580 eina_list_append(cfdata->selected.unloaded, cfm);
581 e_widget_disabled_set(cfdata->b_load, 0);
582 e_widget_disabled_set(cfdata->b_unload, 1);
583 }
584 }
585
586 if ((cfm) && (eina_list_count(cfdata->selected.loaded) + eina_list_count(cfdata->selected.unloaded) == 1))
587 description = cfm->comment;
588 else if (eina_list_count(cfdata->selected.loaded) + eina_list_count(cfdata->selected.unloaded) > 1)
589 description = _("More than one module selected.");
590 else
591 description = _("No modules selected.");
592
593 e_widget_textblock_markup_set(cfdata->o_desc, description);
594 }
595
596 static void
_btn_cb_unload(void * data,void * data2 EINA_UNUSED)597 _btn_cb_unload(void *data, void *data2 EINA_UNUSED)
598 {
599 E_Config_Dialog_Data *cfdata = data;
600 CFModule *cfm;
601
602 EINA_LIST_FREE(cfdata->selected.loaded, cfm)
603 {
604 if (!cfm->module)
605 cfm->module = e_module_find(cfm->short_name);
606
607 if (cfm->module)
608 {
609 e_module_disable(cfm->module);
610 cfm->enabled = e_module_enabled_get(cfm->module);
611 }
612
613 _module_end_state_apply(cfm);
614 cfdata->selected.unloaded = eina_list_append(cfdata->selected.unloaded, cfm);
615 }
616
617 e_widget_disabled_set(cfdata->b_unload, 1);
618 e_widget_disabled_set(cfdata->b_load, 0);
619 }
620
621 static void
_btn_cb_load(void * data,void * data2 EINA_UNUSED)622 _btn_cb_load(void *data, void *data2 EINA_UNUSED)
623 {
624 E_Config_Dialog_Data *cfdata = data;
625 CFModule *cfm;
626
627 EINA_LIST_FREE(cfdata->selected.unloaded, cfm)
628 {
629 if (!cfm->module)
630 cfm->module = e_module_find(cfm->short_name);
631 if (!cfm->module)
632 cfm->module = e_module_new(cfm->short_name);
633
634 if (cfm->module)
635 {
636 e_module_enable(cfm->module);
637 cfm->enabled = e_module_enabled_get(cfm->module);
638 }
639
640 _module_end_state_apply(cfm);
641 cfdata->selected.loaded = eina_list_append(cfdata->selected.loaded, cfm);
642 }
643
644 e_widget_disabled_set(cfdata->b_load, 1);
645 e_widget_disabled_set(cfdata->b_unload, 0);
646 }
647
648