07ccdd040f73b63ccebda0ea70fa5495d96e9ac5
[platform/upstream/enlightenment.git] / src / modules / xkbswitch / e_mod_config.c
1 #include "e.h"
2 #include "e_mod_main.h"
3 #include "e_mod_parse.h"
4
5 struct _E_Config_Dialog_Data
6 {
7    Evas        *evas, *dlg_evas;
8    Evas_Object *layout_list, *used_list;
9    Evas_Object *dmodel_list, *model_list, *variant_list;
10    Evas_Object *btn_add, *btn_del, *btn_up, *btn_down;
11    Ecore_Timer *fill_delay;
12    Ecore_Timer *dlg_fill_delay;
13
14    Eina_List   *cfg_layouts;
15    Eina_List   *cfg_options;
16    const char  *default_model;
17
18    int          only_label;
19    int          dont_touch_my_damn_keyboard;
20
21    E_Dialog    *dlg_add_new;
22 };
23
24 typedef struct _E_XKB_Dialog_Option
25 {
26    int         enabled;
27    const char *name;
28 } E_XKB_Dialog_Option;
29
30 /* Local prototypes */
31
32 static void        *_create_data(E_Config_Dialog *cfd);
33 static void         _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
34 static Evas_Object *_basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
35 static int          _basic_apply(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
36 static int          _basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
37
38 static void         _cb_add(void *data, void *data2 __UNUSED__);
39 static void         _cb_del(void *data, void *data2 __UNUSED__);
40
41 static void         _cb_up(void *data, void *data2 __UNUSED__);
42 static void         _cb_dn(void *data, void *data2 __UNUSED__);
43
44 static void         _dlg_add_cb_ok(void *data, E_Dialog *dlg);
45 static void         _dlg_add_cb_cancel(void *data, E_Dialog *dlg);
46
47 static E_Dialog    *_dlg_add_new(E_Config_Dialog_Data *cfdata);
48
49 static void         _dlg_add_cb_del(void *obj);
50
51 static Eina_Bool    _cb_dlg_fill_delay(void *data);
52
53 static void         _cb_layout_select(void *data);
54 static void         _cb_used_select(void *data);
55
56 static Eina_Bool    _cb_fill_delay(void *data);
57
58 /* Externals */
59
60 E_Config_Dialog *
61 _xkb_cfg_dialog(Evas_Object *parent EINA_UNUSED, const char *params __UNUSED__)
62 {
63    E_Config_Dialog *cfd;
64    E_Config_Dialog_View *v;
65
66    if (e_config_dialog_find("E", "keyboard_and_mouse/xkbswitch"))
67      return NULL;
68    if (!(v = E_NEW(E_Config_Dialog_View, 1))) return NULL;
69
70    v->create_cfdata = _create_data;
71    v->free_cfdata = _free_data;
72    v->basic.create_widgets = _basic_create;
73    v->basic.apply_cfdata = _basic_apply;
74    v->basic.check_changed = _basic_check_changed;
75
76    cfd = e_config_dialog_new(NULL, _("Keyboard Settings"), "E",
77                              "keyboard_and_mouse/xkbswitch",
78                              "preferences-desktop-keyboard",
79                              0, v, NULL);
80    _xkb.cfd = cfd;
81    return cfd;
82 }
83
84 /* Locals */
85
86 static void *
87 _create_data(E_Config_Dialog *cfd __UNUSED__)
88 {
89    E_Config_Dialog_Data *cfdata;
90    Eina_List *l, *ll, *lll;
91    E_Config_XKB_Layout *cl, *nl;
92    E_XKB_Dialog_Option *od;
93    E_XKB_Option *op;
94    E_XKB_Option_Group *gr;
95
96    find_rules();
97    parse_rules(); /* XXX: handle in case nothing was found? */
98
99    cfdata = E_NEW(E_Config_Dialog_Data, 1);
100
101    cfdata->cfg_layouts = NULL;
102    EINA_LIST_FOREACH(e_config->xkb.used_layouts, l, cl)
103      {
104         nl = E_NEW(E_Config_XKB_Layout, 1);
105         nl->name = eina_stringshare_add(cl->name);
106         nl->model = eina_stringshare_add(cl->model);
107         nl->variant = eina_stringshare_add(cl->variant);
108
109         cfdata->cfg_layouts = eina_list_append(cfdata->cfg_layouts, nl);
110      }
111
112    /* Initialize options */
113
114    cfdata->only_label = e_config->xkb.only_label;
115    cfdata->dont_touch_my_damn_keyboard = e_config->xkb.dont_touch_my_damn_keyboard;
116    cfdata->cfg_options = NULL;
117
118    lll = e_config->xkb.used_options;
119    EINA_LIST_FOREACH(optgroups, l, gr)
120      {
121         EINA_LIST_FOREACH(gr->options, ll, op)
122           {
123              od = E_NEW(E_XKB_Dialog_Option, 1);
124              od->name = eina_stringshare_add(op->name);
125              if (lll &&
126                  (od->name == ((E_Config_XKB_Option *)
127                                eina_list_data_get(lll))->name))
128                {
129                   od->enabled = 1;
130                   lll = eina_list_next(lll);
131                }
132              else od->enabled = 0;
133              cfdata->cfg_options = eina_list_append(cfdata->cfg_options, od);
134           }
135      }
136
137    return cfdata;
138 }
139
140 static void
141 _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
142 {
143    E_Config_XKB_Layout *cl;
144    E_XKB_Dialog_Option *od;
145
146    _xkb.cfd = NULL;
147
148    EINA_LIST_FREE(cfdata->cfg_layouts, cl)
149      {
150         eina_stringshare_del(cl->name);
151         eina_stringshare_del(cl->model);
152         eina_stringshare_del(cl->variant);
153         E_FREE(cl);
154      }
155
156    EINA_LIST_FREE(cfdata->cfg_options, od)
157      {
158         eina_stringshare_del(od->name);
159         E_FREE(od);
160      }
161
162    eina_stringshare_del(cfdata->default_model);
163    E_FREE(cfdata);
164    clear_rules();
165 }
166
167 static int
168 _basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
169 {
170    Eina_List *l, *l2, *l3;
171    E_Config_XKB_Layout *cl, *nl;
172    E_Config_XKB_Option *co;
173    E_XKB_Dialog_Option *od;
174    Eina_Bool found;
175
176    if ((eina_list_count(e_config->xkb.used_layouts) !=
177          eina_list_count(cfdata->cfg_layouts)) ||
178        (e_config->xkb.default_model != cfdata->default_model) ||
179        (e_config->xkb.only_label != cfdata->only_label) ||
180        (e_config->xkb.dont_touch_my_damn_keyboard != cfdata->dont_touch_my_damn_keyboard))
181      return 1;
182
183    l2 = cfdata->cfg_layouts;
184    EINA_LIST_FOREACH(e_config->xkb.used_layouts, l, cl)
185      {
186         nl = eina_list_data_get(l2);
187         if ((cl->name != nl->name) ||
188             (cl->model != nl->model) ||
189             (cl->variant != nl->variant))
190           return 1;
191         l2 = eina_list_next(l2);
192      }
193
194    l2 = e_config->xkb.used_options;
195    EINA_LIST_FOREACH(cfdata->cfg_options, l, od)
196      {
197         found = EINA_FALSE;
198         EINA_LIST_FOREACH(l2, l3, co)
199           {
200              if (od->name == co->name)
201                {
202                   found = EINA_TRUE;
203                   break;
204                }
205           }
206         if ((!found) && (!od->enabled))
207           continue;
208         if (found && od->enabled)
209           {
210              l2 = eina_list_next(l3);
211              continue;
212           }
213         return 1;
214      }
215
216    return 0;
217 }
218
219 static int
220 _basic_apply(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
221 {
222    Eina_List *l;
223    E_Config_XKB_Layout *cl, *nl;
224    E_Config_XKB_Option *oc;
225    E_XKB_Dialog_Option *od;
226
227    EINA_LIST_FREE(e_config->xkb.used_layouts, cl)
228      {
229         eina_stringshare_del(cl->name);
230         eina_stringshare_del(cl->model);
231         eina_stringshare_del(cl->variant);
232         E_FREE(cl);
233      }
234
235    EINA_LIST_FOREACH(cfdata->cfg_layouts, l, cl)
236      {
237         nl = E_NEW(E_Config_XKB_Layout, 1);
238         nl->name = eina_stringshare_ref(cl->name);
239         nl->model = eina_stringshare_ref(cl->model);
240         nl->variant = eina_stringshare_ref(cl->variant);
241
242         e_config->xkb.used_layouts =
243           eina_list_append(e_config->xkb.used_layouts, nl);
244      }
245
246    eina_stringshare_replace(&e_config->xkb.default_model, cfdata->default_model);
247
248    /* Save options */
249    e_config->xkb.only_label = cfdata->only_label;
250    e_config->xkb.dont_touch_my_damn_keyboard = cfdata->dont_touch_my_damn_keyboard;
251
252    EINA_LIST_FREE(e_config->xkb.used_options, oc)
253      {
254         eina_stringshare_del(oc->name);
255         E_FREE(oc);
256      }
257
258    EINA_LIST_FOREACH(cfdata->cfg_options, l, od)
259      {
260         if (!od->enabled) continue;
261
262         oc = E_NEW(E_Config_XKB_Option, 1);
263         oc->name = eina_stringshare_ref(od->name);
264         e_config->xkb.used_options = eina_list_append(e_config->xkb.used_options, oc);
265      }
266
267    e_xkb_update(-1);
268    _xkb_update_icon(0);
269
270    e_config_save_queue();
271    return 1;
272 }
273
274 static Evas_Object *
275 _basic_create(E_Config_Dialog *cfd EINA_UNUSED, Evas *evas, E_Config_Dialog_Data *cfdata)
276 {
277    Evas_Object *mainn, *layoutss, *modelss, *options, *configs, *buttons,
278      *general, *scroller, *only_label, *dont_touch_my_damn_keyboard;
279    E_XKB_Option *option;
280    E_XKB_Option_Group *group;
281    Eina_List *l, *ll, *lll;
282    Evas_Coord mw, mh;
283    /* Holds the dialog contents, displays a toolbar on the top */
284    e_dialog_resizable_set(cfd->dia, 1);
285    mainn = e_widget_toolbook_add(evas, 24, 24);
286
287    /* Holds the used layouts ilist and the button table */
288    layoutss = e_widget_list_add(evas, 0, 0);
289
290    /* Holds the used layouts */
291    configs = e_widget_ilist_add(evas, 32, 32, NULL);
292
293    e_widget_size_min_set(configs, 220, 160);
294    e_widget_ilist_go(configs);
295
296    e_widget_list_object_append(layoutss, configs, 1, 1, 0.5);
297    cfdata->used_list = configs;
298
299    /* Holds the buttons */
300    buttons = e_widget_table_add(evas, 1);
301    cfdata->btn_up = e_widget_button_add(evas, _("Up"), "go-up", _cb_up, cfdata, NULL);
302    e_widget_disabled_set(cfdata->btn_up, EINA_TRUE);
303    e_widget_table_object_append(buttons, cfdata->btn_up, 0, 0, 1, 1, 1, 1, 1, 0);
304
305    cfdata->btn_down = e_widget_button_add(evas, _("Down"), "go-down", _cb_dn, cfdata, NULL);
306    e_widget_disabled_set(cfdata->btn_down, EINA_TRUE);
307    e_widget_table_object_append(buttons, cfdata->btn_down, 1, 0, 1, 1, 1, 1, 1, 0);
308
309    cfdata->btn_add = e_widget_button_add(evas, _("Add"), "list-add", _cb_add, cfdata, NULL);
310    e_widget_table_object_append(buttons, cfdata->btn_add, 0, 1, 1, 1, 1, 1, 1, 0);
311
312    cfdata->btn_del = e_widget_button_add(evas, _("Remove"), "list-remove", _cb_del, cfdata, NULL);
313    e_widget_disabled_set(cfdata->btn_del, EINA_TRUE);
314    e_widget_table_object_append(buttons, cfdata->btn_del, 1, 1, 1, 1, 1, 1, 1, 0);
315
316    e_widget_list_object_append(layoutss, buttons, 1, 0, 1);
317
318    e_widget_toolbook_page_append(mainn, NULL, _("Configurations"), layoutss, 1, 1, 1, 1, 0.5, 0.0);
319
320    /* Holds the default models */
321    modelss = e_widget_ilist_add(evas, 32, 32, &cfdata->default_model);
322    e_widget_size_min_set(modelss, 220, 160);
323    cfdata->dmodel_list = modelss;
324
325    e_widget_toolbook_page_append(mainn, NULL, _("Models"), modelss, 1, 1, 1, 1, 0.5, 0.0);
326
327    /* Holds the options */
328    options = e_widget_list_add(evas, 0, 0);
329
330    general = e_widget_framelist_add(evas, _("General"), 0);
331    dont_touch_my_damn_keyboard = e_widget_check_add(evas, _("Do not apply any keyboard settings ever"), &(cfdata->dont_touch_my_damn_keyboard));
332    e_widget_framelist_object_append(general, dont_touch_my_damn_keyboard);
333    only_label = e_widget_check_add(evas, _("Label only in gadgets"), &(cfdata->only_label));
334    e_widget_check_widget_disable_on_checked_add(dont_touch_my_damn_keyboard, only_label);
335    e_widget_framelist_object_append(general, only_label);
336    e_widget_list_object_append(options, general, 1, 1, 0.0);
337
338    lll = cfdata->cfg_options;
339
340    EINA_LIST_FOREACH(optgroups, l, group)
341      {
342         Evas_Object *grp;
343
344         grp = e_widget_framelist_add(evas, group->description, 0);
345
346         EINA_LIST_FOREACH(group->options, ll, option)
347           {
348              Evas_Object *chk;
349
350              chk = e_widget_check_add(evas, option->description,
351                                      &(((E_XKB_Dialog_Option *)
352                                         eina_list_data_get(lll))->enabled));
353              e_widget_check_widget_disable_on_checked_add(dont_touch_my_damn_keyboard, chk);
354              e_widget_framelist_object_append(grp, chk);
355              lll = eina_list_next(lll);
356           }
357         e_widget_list_object_append(options, grp, 1, 1, 0.0);
358      }
359
360    e_widget_size_min_get(options, &mw, &mh);
361
362    if (mw < 220) mw = 220;
363    if (mh < 160) mh = 160;
364
365    evas_object_resize(options, mw, mh);
366
367    scroller = e_widget_scrollframe_simple_add(evas, options);
368    e_widget_size_min_set(scroller, 220, 160);
369
370    e_widget_toolbook_page_append(mainn, NULL, _("Options"), scroller, 1, 1, 1, 1, 0.5, 0.0);
371
372    /* Display the first page by default */
373    e_widget_toolbook_page_show(mainn, 0);
374
375    /* The main evas */
376    cfdata->evas = evas;
377
378    /* Clear up any previous timer */
379    if (cfdata->fill_delay)
380      ecore_timer_del(cfdata->fill_delay);
381
382    /* Trigger the fill */
383    cfdata->fill_delay = ecore_timer_add(0.2, _cb_fill_delay, cfdata);
384
385    return mainn;
386 }
387
388 static void
389 _cb_add(void *data, void *data2 __UNUSED__)
390 {
391    E_Config_Dialog_Data *cfdata;
392    if (!(cfdata = data)) return;
393
394    if (cfdata->dlg_add_new) elm_win_raise(cfdata->dlg_add_new->win);
395    else cfdata->dlg_add_new = _dlg_add_new(cfdata);
396 }
397
398 static void
399 _cb_del(void *data, void *data2 __UNUSED__)
400 {
401    E_Config_Dialog_Data *cfdata;
402    int n = 0;
403
404    if (!(cfdata = data)) return;
405    if ((n = e_widget_ilist_selected_get(cfdata->used_list)) < 0) return;
406
407    cfdata->cfg_layouts = eina_list_remove_list(cfdata->cfg_layouts, eina_list_nth_list(cfdata->cfg_layouts, n));
408
409    /* Update the list */
410    evas_event_freeze(cfdata->evas);
411    edje_freeze();
412    e_widget_ilist_freeze(cfdata->used_list);
413    e_widget_ilist_remove_num(cfdata->used_list, n);
414    e_widget_ilist_go(cfdata->used_list);
415    e_widget_ilist_thaw(cfdata->used_list);
416    edje_thaw();
417    evas_event_thaw(cfdata->evas);
418 }
419
420 static void
421 _cb_up(void *data, void *data2 __UNUSED__)
422 {
423    E_Config_Dialog_Data *cfdata;
424    void *nddata;
425    Evas_Object *ic;
426    Eina_List *l;
427    const char *lbl, *file;
428    int n;
429
430    if (!(cfdata = data)) return;
431    if ((n = e_widget_ilist_selected_get(cfdata->used_list)) < 0) return;
432
433    l = eina_list_nth_list(cfdata->cfg_layouts, n);
434
435    nddata = eina_list_data_get(eina_list_prev(l));
436    eina_list_data_set(eina_list_prev(l), eina_list_data_get(l));
437    eina_list_data_set(l, nddata);
438
439    /* Update the list */
440
441    evas_event_freeze(cfdata->evas);
442    edje_freeze();
443    e_widget_ilist_freeze(cfdata->used_list);
444
445    ic = e_icon_add(cfdata->evas);
446    e_icon_file_get(e_widget_ilist_nth_icon_get(cfdata->used_list, n), &file, NULL);
447    e_icon_file_set(ic, file);
448    lbl = e_widget_ilist_nth_label_get(cfdata->used_list, n);
449    e_widget_ilist_prepend_relative_full(cfdata->used_list, ic, NULL, lbl, _cb_used_select, cfdata, NULL, (n - 1));
450    e_widget_ilist_remove_num(cfdata->used_list, n);
451
452    e_widget_ilist_go(cfdata->used_list);
453    e_widget_ilist_thaw(cfdata->used_list);
454    edje_thaw();
455    evas_event_thaw(cfdata->evas);
456
457    e_widget_ilist_selected_set(cfdata->used_list, (n - 1));
458 }
459
460 static void
461 _cb_dn(void *data, void *data2 __UNUSED__)
462 {
463    E_Config_Dialog_Data *cfdata;
464    void *nddata;
465    Evas_Object *ic;
466    Eina_List *l;
467    const char *lbl, *file;
468    int n;
469
470    if (!(cfdata = data)) return;
471    if ((n = e_widget_ilist_selected_get(cfdata->used_list)) < 0) return;
472
473    l = eina_list_nth_list(cfdata->cfg_layouts, n);
474
475    nddata = eina_list_data_get(eina_list_next(l));
476    eina_list_data_set(eina_list_next(l), eina_list_data_get(l));
477    eina_list_data_set(l, nddata);
478
479    /* Update the list */
480
481    evas_event_freeze(cfdata->evas);
482    edje_freeze();
483    e_widget_ilist_freeze(cfdata->used_list);
484
485    ic = e_icon_add(cfdata->evas);
486    e_icon_file_get(e_widget_ilist_nth_icon_get(cfdata->used_list, n), &file, NULL);
487    e_icon_file_set(ic, file);
488    lbl = e_widget_ilist_nth_label_get(cfdata->used_list, n);
489    e_widget_ilist_append_relative_full(cfdata->used_list, ic, NULL, lbl, _cb_used_select, cfdata, NULL, n);
490    e_widget_ilist_remove_num(cfdata->used_list, n);
491
492    e_widget_ilist_go(cfdata->used_list);
493    e_widget_ilist_thaw(cfdata->used_list);
494    edje_thaw();
495    evas_event_thaw(cfdata->evas);
496
497    e_widget_ilist_selected_set(cfdata->used_list, (n + 1));
498 }
499
500 static E_Dialog *
501 _dlg_add_new(E_Config_Dialog_Data *cfdata)
502 {
503    E_Dialog *dlg;
504    Evas *evas;
505    Evas_Coord mw, mh;
506    Evas_Object *mainn, *available, *modelss, *variants;
507
508    if (!(dlg = e_dialog_new(NULL, "E", "xkbswitch_config_add_dialog"))) return NULL;
509
510    e_dialog_resizable_set(dlg, 1);
511    dlg->data = cfdata;
512    
513    e_object_del_attach_func_set(E_OBJECT(dlg), _dlg_add_cb_del);
514    elm_win_center(dlg->win, 1, 1);
515
516    evas = evas_object_evas_get(dlg->win);
517    e_dialog_title_set(dlg, _("Add New Configuration"));
518
519    /* The main toolbook, holds the lists and tabs */
520    mainn = e_widget_toolbook_add(evas, 24, 24);
521    /* Holds the available layouts */
522    available = e_widget_ilist_add(evas, 32, 32, NULL);
523
524    e_widget_size_min_set(available, 220, 160);
525    e_widget_ilist_go(available);
526    e_widget_toolbook_page_append(mainn, NULL, _("Available"), available, 1, 1, 1, 1, 0.5, 0.0);
527    cfdata->layout_list = available;
528
529    /* Holds the available models */
530    modelss = e_widget_ilist_add(evas, 32, 32, NULL);
531    e_widget_toolbook_page_append(mainn, NULL, _("Model"), modelss, 1, 1, 1, 1, 0.5, 0.0);
532    cfdata->model_list = modelss;
533
534    /* Holds the available variants */
535    variants = e_widget_ilist_add(evas, 32, 32, NULL);
536    e_widget_toolbook_page_append(mainn, NULL, _("Variant"), variants, 1, 1, 1, 1, 0.5, 0.0);
537    cfdata->variant_list = variants;
538    e_widget_toolbook_page_show(mainn, 0);
539
540    e_widget_size_min_get(mainn, &mw, &mh);
541    e_dialog_content_set(dlg, mainn, mw, mh);
542
543    cfdata->dlg_evas = evas;
544
545    /* Clear up any previous timer */
546    if (cfdata->dlg_fill_delay) ecore_timer_del(cfdata->dlg_fill_delay);
547
548    /* Trigger the fill */
549    cfdata->dlg_fill_delay = ecore_timer_add(0.2, _cb_dlg_fill_delay, cfdata);
550
551    /* Some buttons */
552    e_dialog_button_add(dlg, _("OK"), NULL, _dlg_add_cb_ok, cfdata);
553    e_dialog_button_add(dlg, _("Cancel"), NULL, _dlg_add_cb_cancel, cfdata);
554
555    e_dialog_button_disable_num_set(dlg, 0, 1);
556    e_dialog_button_disable_num_set(dlg, 1, 0);
557
558    e_dialog_show(dlg);
559
560    return dlg;
561 }
562
563 static void
564 _dlg_add_cb_ok(void *data __UNUSED__, E_Dialog *dlg)
565 {
566    E_Config_Dialog_Data *cfdata = dlg->data;
567    E_Config_XKB_Layout *cl;
568    char buf[4096];
569    Evas_Object *ic;
570    /* Configuration information */
571    Eina_Stringshare *layout, *model, *variant;
572
573    layout = e_widget_ilist_selected_value_get(cfdata->layout_list);
574    model = e_widget_ilist_selected_value_get(cfdata->model_list);
575    variant = e_widget_ilist_selected_value_get(cfdata->variant_list);
576
577    /* The new configuration */
578    cl = E_NEW(E_Config_XKB_Layout, 1);
579    cl->name = eina_stringshare_ref(layout);
580    cl->model = eina_stringshare_ref(model);
581    cl->variant = eina_stringshare_ref(variant);
582
583    cfdata->cfg_layouts = eina_list_append(cfdata->cfg_layouts, cl);
584
585    /* Update the main list */
586    evas_event_freeze(cfdata->evas);
587    edje_freeze();
588    e_widget_ilist_freeze(cfdata->used_list);
589
590    ic = e_icon_add(cfdata->evas);
591
592    e_xkb_e_icon_flag_setup(ic, cl->name);
593    snprintf(buf, sizeof(buf), "%s (%s, %s)",
594             cl->name, cl->model, cl->variant);
595    e_widget_ilist_append_full(cfdata->used_list, ic, NULL, buf,
596                               _cb_used_select, cfdata, NULL);
597
598    e_widget_ilist_go(cfdata->used_list);
599    e_widget_ilist_thaw(cfdata->used_list);
600    edje_thaw();
601    evas_event_thaw(cfdata->evas);
602
603    cfdata->dlg_add_new = NULL;
604    e_object_unref(E_OBJECT(dlg));
605 }
606
607 static void
608 _dlg_add_cb_cancel(void *data __UNUSED__, E_Dialog *dlg)
609 {
610    E_Config_Dialog_Data *cfdata = dlg->data;
611    cfdata->dlg_add_new = NULL;
612    e_object_unref(E_OBJECT(dlg));
613 }
614
615 static void
616 _dlg_add_cb_del(void *obj)
617 {
618    E_Dialog *dlg = obj;
619    E_Config_Dialog_Data *cfdata = dlg->data;
620    cfdata->dlg_add_new = NULL;
621    e_object_unref(E_OBJECT(dlg));
622 }
623
624 static Eina_Bool
625 _cb_dlg_fill_delay(void *data)
626 {
627    E_Config_Dialog_Data *cfdata;
628    Eina_List *l;
629    E_XKB_Layout *layout;
630    char buf[4096];
631
632    if (!(cfdata = data)) return ECORE_CALLBACK_RENEW;
633
634    /* Update the list of available layouts */
635    evas_event_freeze(cfdata->dlg_evas);
636    edje_freeze();
637
638    e_widget_ilist_freeze(cfdata->layout_list);
639    e_widget_ilist_clear(cfdata->layout_list);
640
641    EINA_LIST_FOREACH(layouts, l, layout)
642      {
643         Evas_Object *ic;
644
645         ic = e_icon_add(cfdata->dlg_evas);
646         e_xkb_e_icon_flag_setup(ic, layout->name);
647         snprintf(buf, sizeof(buf), "%s (%s)",
648                  layout->description, layout->name);
649         e_widget_ilist_append_full(cfdata->layout_list, ic, NULL, buf,
650                                    _cb_layout_select, cfdata, layout->name);
651      }
652
653    e_widget_ilist_go(cfdata->layout_list);
654    e_widget_ilist_thaw(cfdata->layout_list);
655
656    edje_thaw();
657    evas_event_thaw(cfdata->dlg_evas);
658
659    cfdata->dlg_fill_delay = NULL;
660    return ECORE_CALLBACK_CANCEL;
661 }
662
663 static void
664 _cb_layout_select(void *data)
665 {
666    E_Config_Dialog_Data *cfdata;
667    E_XKB_Variant *variant;
668    E_XKB_Layout *layout;
669    E_XKB_Model *model;
670    Eina_List *l;
671    const char *label;
672    int n;
673    char buf[4096];
674
675    if (!(cfdata = data)) return;
676
677    /* Find the right layout */
678
679    if ((n = e_widget_ilist_selected_get(cfdata->layout_list)) < 0)
680      return;
681    if (!(label = e_widget_ilist_nth_label_get(cfdata->layout_list, n)))
682      return;
683
684    if (!(layout = eina_list_search_unsorted
685              (layouts, layout_sort_by_name_cb,
686              e_widget_ilist_nth_value_get(cfdata->layout_list, n)
687              ))) return;
688
689    /* Update the lists */
690    evas_event_freeze(cfdata->dlg_evas);
691    edje_freeze();
692
693    /* Models */
694    e_widget_ilist_freeze(cfdata->model_list);
695    e_widget_ilist_clear(cfdata->model_list);
696
697    EINA_LIST_FOREACH(models, l, model)
698      {
699         snprintf(buf, sizeof(buf), "%s (%s)", model->description, model->name);
700         e_widget_ilist_append(cfdata->model_list, NULL, buf, NULL, cfdata, model->name);
701      }
702
703    e_widget_ilist_go(cfdata->model_list);
704    e_widget_ilist_thaw(cfdata->model_list);
705
706    /* Variants */
707    e_widget_ilist_freeze(cfdata->variant_list);
708    e_widget_ilist_clear(cfdata->variant_list);
709
710    EINA_LIST_FOREACH(layout->variants, l, variant)
711      {
712         snprintf(buf, sizeof(buf), "%s (%s)", variant->name, variant->description);
713         e_widget_ilist_append(cfdata->variant_list, NULL, buf, NULL, cfdata, variant->name);
714      }
715
716    e_widget_ilist_go(cfdata->variant_list);
717    e_widget_ilist_thaw(cfdata->variant_list);
718
719    edje_thaw();
720    evas_event_thaw(cfdata->dlg_evas);
721
722    e_widget_ilist_selected_set(cfdata->model_list, 0);
723    e_widget_ilist_selected_set(cfdata->variant_list, 0);
724
725    e_dialog_button_disable_num_set(cfdata->dlg_add_new, 0, 0);
726 }
727
728 static Eina_Bool
729 _cb_fill_delay(void *data)
730 {
731    E_Config_Dialog_Data *cfdata;
732    Eina_List *l;
733    E_Config_XKB_Layout *cl;
734    E_XKB_Model *model;
735    int n = 0;
736    char buf[4096];
737
738    if (!(cfdata = data)) return ECORE_CALLBACK_RENEW;
739
740    /* Update the list of used layouts */
741    evas_event_freeze(cfdata->evas);
742    edje_freeze();
743
744    e_widget_ilist_freeze(cfdata->used_list);
745    e_widget_ilist_clear(cfdata->used_list);
746
747    EINA_LIST_FOREACH(cfdata->cfg_layouts, l, cl)
748      {
749         Evas_Object *ic = e_icon_add(cfdata->evas);
750         const char *name = cl->name;
751
752         e_xkb_e_icon_flag_setup(ic, name);
753         snprintf(buf, sizeof(buf), "%s (%s, %s)",
754                  cl->name, cl->model, cl->variant);
755         e_widget_ilist_append_full(cfdata->used_list, ic, NULL, buf,
756                                    _cb_used_select, cfdata, NULL);
757      }
758
759    e_widget_ilist_go(cfdata->used_list);
760    e_widget_ilist_thaw(cfdata->used_list);
761
762    e_widget_ilist_freeze(cfdata->dmodel_list);
763    e_widget_ilist_clear(cfdata->dmodel_list);
764
765    /* Update the global model list */
766    EINA_LIST_FOREACH(models, l, model)
767      {
768         snprintf(buf, sizeof(buf), "%s (%s)", model->description, model->name);
769         e_widget_ilist_append(cfdata->dmodel_list, NULL, buf, NULL,
770                               cfdata, model->name);
771         if (model->name == e_config->xkb.default_model)
772           e_widget_ilist_selected_set(cfdata->dmodel_list, n);
773         n++;
774      }
775
776    e_widget_ilist_go(cfdata->dmodel_list);
777    e_widget_ilist_thaw(cfdata->dmodel_list);
778    edje_thaw();
779    evas_event_thaw(cfdata->evas);
780
781    cfdata->fill_delay = NULL;
782    return ECORE_CALLBACK_CANCEL;
783 }
784
785 static void
786 _cb_used_select(void *data)
787 {
788    E_Config_Dialog_Data *cfdata;
789    int n, c;
790
791    if (!(cfdata = data)) return;
792    if ((n = e_widget_ilist_selected_get(cfdata->used_list)) < 0) return;
793
794    c = e_widget_ilist_count(cfdata->used_list);
795    e_widget_disabled_set(cfdata->btn_del, EINA_FALSE);
796
797    if (c == 1)
798      {
799         e_widget_disabled_set(cfdata->btn_up, EINA_TRUE);
800         e_widget_disabled_set(cfdata->btn_down, EINA_TRUE);
801      }
802    else if (n == (c - 1))
803      {
804         e_widget_disabled_set(cfdata->btn_up, EINA_FALSE);
805         e_widget_disabled_set(cfdata->btn_down, EINA_TRUE);
806      }
807    else if (n == 0)
808      {
809         e_widget_disabled_set(cfdata->btn_up, EINA_TRUE);
810         e_widget_disabled_set(cfdata->btn_down, EINA_FALSE);
811      }
812    else
813      {
814         e_widget_disabled_set(cfdata->btn_up, EINA_FALSE);
815         e_widget_disabled_set(cfdata->btn_down, EINA_FALSE);
816      }
817 }
818