e_table -> elm_table conversion
[platform/upstream/enlightenment.git] / src / modules / conf_bindings / e_int_config_edgebindings.c
1
2 #include "e.h"
3
4 #define TEXT_NONE_ACTION_EDGE    _("<None>")
5 #define TEXT_PRESS_EDGE_SEQUENCE _("Please select an edge,<br>"                               \
6                                    "or click <hilight>Close</hilight> to abort.<br><br>"      \
7                                    "You can either specify a delay of this<br> action using " \
8                                    "the slider, or make it<br>respond to edge clicks:"        \
9                                    )
10
11 #define TEXT_NO_PARAMS           _("<None>")
12
13 static void        *_create_data(E_Config_Dialog *cfd);
14 static void         _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
15 static int          _basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
16 static Evas_Object *_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas,
17                                           E_Config_Dialog_Data *cfdata);
18
19 /********* private functions ***************/
20 static void         _fill_actions_list(E_Config_Dialog_Data *cfdata);
21
22 /**************** Updates ***********/
23 static void         _update_edge_binding_list(E_Config_Dialog_Data *cfdata);
24 static void         _update_action_list(E_Config_Dialog_Data *cfdata);
25 static void         _update_action_params(E_Config_Dialog_Data *cfdata);
26 static void         _update_buttons(E_Config_Dialog_Data *cfdata);
27
28 /**************** Callbacks *********/
29 static void         _binding_change_cb(void *data);
30 static void         _action_change_cb(void *data);
31 static void         _delete_all_edge_binding_cb(void *data, void *data2);
32 static void         _delete_edge_binding_cb(void *data, void *data2);
33 static void         _restore_edge_binding_defaults_cb(void *data, void *data2);
34 static void         _add_edge_binding_cb(void *data, void *data2);
35 static void         _modify_edge_binding_cb(void *data, void *data2);
36
37 /********* Helper *************************/
38 static char        *_edge_binding_text_get(E_Zone_Edge edge, float delay, int mod);
39 static void         _auto_apply_changes(E_Config_Dialog_Data *cfdata);
40 static void         _find_edge_binding_action(const char *action, const char *params, int *g, int *a, int *n);
41
42 /********* Sorting ************************/
43 static int          _edge_binding_sort_cb(const void *d1, const void *d2);
44
45 /**************** grab window *******/
46 static void         _edge_grab_wnd_show(E_Config_Dialog_Data *cfdata);
47 static void         _edge_grab_wnd_cb_apply(void *data, E_Dialog *dia);
48 static void         _edge_grab_wnd_cb_close(void *data, E_Dialog *dia);
49 static void         _edge_grab_wnd_slider_changed_cb(void *data, Evas_Object *obj);
50 static void         _edge_grab_wnd_check_changed_cb(void *data, Evas_Object *obj);
51 static void         _edge_grab_wnd_selected_edge_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
52 static void         _edge_grab_wnd_selection_apply(E_Config_Dialog_Data *cfdata);
53
54 struct _E_Config_Dialog_Data
55 {
56    Evas *evas;
57    struct
58    {
59       Eina_List *edge;
60    } binding;
61    struct
62    {
63       const char *binding, *action;
64       char       *params;
65       const char *cur;
66       double      delay;
67       int         click;
68       int         drag_only;
69       int         button;
70       int         cur_act, add;
71       E_Zone_Edge edge;
72       int         modifiers;
73
74       E_Dialog   *dia;
75    } locals;
76    struct
77    {
78       Evas_Object *o_add, *o_mod, *o_del, *o_del_all;
79       Evas_Object *o_binding_list, *o_action_list;
80       Evas_Object *o_params, *o_selector, *o_slider, *o_check, *o_check2, *o_button;
81    } gui;
82
83    const char      *params;
84
85    int              fullscreen_flip;
86    int              multiscreen_flip;
87
88    E_Config_Dialog *cfd;
89 };
90
91 E_Config_Dialog *
92 e_int_config_edgebindings(Evas_Object *parent EINA_UNUSED, const char *params)
93 {
94    E_Config_Dialog *cfd;
95    E_Config_Dialog_View *v;
96
97    if (e_config_dialog_find("E", "keyboard_and_mouse/edge_bindings")) return NULL;
98    v = E_NEW(E_Config_Dialog_View, 1);
99
100    v->create_cfdata = _create_data;
101    v->free_cfdata = _free_data;
102    v->basic.apply_cfdata = _basic_apply_data;
103    v->basic.create_widgets = _basic_create_widgets;
104    v->override_auto_apply = 1;
105
106    cfd = e_config_dialog_new(NULL, _("Edge Bindings Settings"), "E",
107                              "keyboard_and_mouse/edge_bindings",
108                              "enlightenment/edges", 0, v, NULL);
109    if ((params) && (params[0]))
110      {
111         cfd->cfdata->params = eina_stringshare_add(params);
112         _add_edge_binding_cb(cfd->cfdata, NULL);
113      }
114
115    return cfd;
116 }
117
118 static void
119 _fill_data(E_Config_Dialog_Data *cfdata)
120 {
121    E_Config_Binding_Edge *bi, *bi2;
122    Eina_List *l;
123
124    cfdata->locals.params = strdup("");
125    cfdata->locals.action = eina_stringshare_add("");
126    cfdata->locals.binding = eina_stringshare_add("");
127    cfdata->locals.cur = NULL;
128    cfdata->locals.dia = NULL;
129    cfdata->locals.delay = 0.3;
130    cfdata->locals.click = 0;
131    cfdata->binding.edge = NULL;
132
133    EINA_LIST_FOREACH(e_bindings->edge_bindings, l, bi)
134      {
135         if (!bi) continue;
136
137         bi2 = E_NEW(E_Config_Binding_Edge, 1);
138         bi2->context = bi->context;
139         bi2->edge = bi->edge;
140         bi2->modifiers = bi->modifiers;
141         bi2->any_mod = bi->any_mod;
142         bi2->delay = bi->delay;
143         bi2->drag_only = bi->drag_only;
144         bi2->action = eina_stringshare_ref(bi->action);
145         bi2->params = eina_stringshare_ref(bi->params);
146
147         cfdata->binding.edge = eina_list_append(cfdata->binding.edge, bi2);
148      }
149
150    cfdata->fullscreen_flip = e_config->fullscreen_flip;
151    cfdata->multiscreen_flip = e_config->multiscreen_flip;
152 }
153
154 static void *
155 _create_data(E_Config_Dialog *cfd)
156 {
157    E_Config_Dialog_Data *cfdata;
158
159    cfdata = E_NEW(E_Config_Dialog_Data, 1);
160    cfdata->cfd = cfd;
161    _fill_data(cfdata);
162
163    return cfdata;
164 }
165
166 static void
167 _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
168 {
169    E_Config_Binding_Edge *bi;
170
171    EINA_LIST_FREE(cfdata->binding.edge, bi)
172      {
173         eina_stringshare_del(bi->action);
174         eina_stringshare_del(bi->params);
175         E_FREE(bi);
176      }
177
178    eina_stringshare_del(cfdata->locals.cur);
179    eina_stringshare_del(cfdata->params);
180    eina_stringshare_del(cfdata->locals.binding);
181    eina_stringshare_del(cfdata->locals.action);
182
183    free(cfdata->locals.params);
184    E_FREE(cfdata);
185 }
186
187 static int
188 _basic_apply_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
189 {
190    const Eina_List *l;
191    E_Zone *zone;
192    E_Config_Binding_Edge *bi, *bi2;
193    E_Layer layer;
194
195    _auto_apply_changes(cfdata);
196
197    EINA_LIST_FREE(e_bindings->edge_bindings, bi)
198      {
199         e_bindings_edge_del(bi->context, bi->edge, bi->drag_only, bi->modifiers, bi->any_mod,
200                             bi->action, bi->params, bi->delay);
201         eina_stringshare_del(bi->action);
202         eina_stringshare_del(bi->params);
203         E_FREE(bi);
204      }
205
206    e_config->multiscreen_flip = cfdata->multiscreen_flip;
207    EINA_LIST_FOREACH(cfdata->binding.edge, l, bi2)
208      {
209         bi = E_NEW(E_Config_Binding_Edge, 1);
210         bi->context = bi2->context;
211         bi->edge = bi2->edge;
212         bi->modifiers = bi2->modifiers;
213         bi->any_mod = bi2->any_mod;
214         bi->delay = bi2->delay;
215         bi->drag_only = bi2->drag_only;
216         bi->action =
217           ((!bi2->action) || (!bi2->action[0])) ? NULL : eina_stringshare_add(bi2->action);
218         bi->params =
219           ((!bi2->params) || (!bi2->params[0])) ? NULL : eina_stringshare_add(bi2->params);
220
221         e_bindings->edge_bindings = eina_list_append(e_bindings->edge_bindings, bi);
222         e_bindings_edge_add(bi->context, bi->edge, bi->drag_only, bi->modifiers, bi->any_mod,
223                             bi->action, bi->params, bi->delay);
224      }
225
226    if (cfdata->fullscreen_flip != e_config->fullscreen_flip)
227      {
228         if (cfdata->fullscreen_flip)
229           layer = E_LAYER_CLIENT_EDGE_FULLSCREEN;
230         else
231           layer = E_LAYER_CLIENT_EDGE;
232
233         EINA_LIST_FOREACH(e_comp->zones, l, zone)
234           e_zone_edge_win_layer_set(zone, layer);
235      }
236
237    e_config->fullscreen_flip = cfdata->fullscreen_flip;
238
239    e_config_save_queue();
240
241    return 1;
242 }
243
244 static Evas_Object *
245 _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
246 {
247    Evas_Object *o, *ol, *ot, *of, *ob;
248
249    cfdata->evas = evas;
250    o = e_widget_list_add(evas, 0, 0);
251    ol = e_widget_list_add(evas, 0, 1);
252
253    of = e_widget_frametable_add(evas, _("Edge Bindings"), 0);
254    ob = e_widget_ilist_add(evas, 32, 32, &(cfdata->locals.binding));
255    cfdata->gui.o_binding_list = ob;
256    e_widget_size_min_set(ob, 200, 160);
257    e_widget_frametable_object_append(of, ob, 0, 0, 2, 1, 1, 1, 1, 1);
258    ob = e_widget_button_add(evas, _("Add"), "list-add", _add_edge_binding_cb, cfdata, NULL);
259    cfdata->gui.o_add = ob;
260    e_widget_frametable_object_append(of, ob, 0, 1, 1, 1, 1, 0, 1, 0);
261    ob = e_widget_button_add(evas, _("Delete"), "list-remove", _delete_edge_binding_cb, cfdata, NULL);
262    cfdata->gui.o_del = ob;
263    e_widget_disabled_set(ob, 1);
264    e_widget_frametable_object_append(of, ob, 1, 1, 1, 1, 1, 0, 1, 0);
265    ob = e_widget_button_add(evas, _("Modify"), NULL, _modify_edge_binding_cb, cfdata, NULL);
266    cfdata->gui.o_mod = ob;
267    e_widget_disabled_set(ob, 1);
268    e_widget_frametable_object_append(of, ob, 0, 2, 1, 1, 1, 0, 1, 0);
269    ob = e_widget_button_add(evas, _("Delete All"), "edit-clear", _delete_all_edge_binding_cb, cfdata, NULL);
270    cfdata->gui.o_del_all = ob;
271    e_widget_disabled_set(ob, 1);
272    e_widget_frametable_object_append(of, ob, 1, 2, 1, 1, 1, 0, 1, 0);
273    ob = e_widget_button_add(evas, _("Restore Default Bindings"), "enlightenment", _restore_edge_binding_defaults_cb, cfdata, NULL);
274    e_widget_frametable_object_append(of, ob, 0, 3, 2, 1, 1, 0, 1, 0);
275    e_widget_list_object_append(ol, of, 1, 1, 0.5);
276
277    ot = e_widget_table_add(e_win_evas_win_get(evas), 0);
278    of = e_widget_framelist_add(evas, _("Action"), 0);
279    ob = e_widget_ilist_add(evas, 24, 24, &(cfdata->locals.action));
280    cfdata->gui.o_action_list = ob;
281    e_widget_size_min_set(ob, 200, 240);
282    e_widget_framelist_object_append(of, ob);
283    e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1);
284
285    of = e_widget_framelist_add(evas, _("Mouse Button"), 0);
286    ob = e_widget_label_add(evas, NULL);
287    e_widget_framelist_object_append(of, ob);
288    e_widget_table_object_append(ot, of, 0, 2, 1, 1, 1, 1, 1, 0);
289    cfdata->gui.o_button = ob;
290
291    of = e_widget_framelist_add(evas, _("Action Params"), 0);
292    ob = e_widget_entry_add(cfd->dia->win, &(cfdata->locals.params), NULL, NULL, NULL);
293    cfdata->gui.o_params = ob;
294    e_widget_disabled_set(ob, 1);
295    e_widget_framelist_object_append(of, ob);
296    e_widget_table_object_append(ot, of, 0, 3, 1, 1, 1, 1, 1, 0);
297    e_widget_list_object_append(ol, ot, 1, 1, 0.5);
298
299    e_widget_list_object_append(o, ol, 1, 1, 0.5);
300
301    of = e_widget_framelist_add(evas, _("General Options"), 0);
302    ob = e_widget_check_add(evas, _("Allow binding activation with fullscreen windows"), &(cfdata->fullscreen_flip));
303    e_widget_framelist_object_append(of, ob);
304    ob = e_widget_check_add(evas, _("Allow binding activation with multiple screens (DANGEROUS!)"), &(cfdata->multiscreen_flip));
305    e_widget_framelist_object_append(of, ob);
306    e_widget_list_object_append(o, of, 1, 0, 0.5);
307
308    _update_edge_binding_list(cfdata);
309    _fill_actions_list(cfdata);
310
311    e_dialog_resizable_set(cfd->dia, 1);
312    return o;
313 }
314
315 static void
316 _fill_actions_list(E_Config_Dialog_Data *cfdata)
317 {
318    char buf[1024];
319    Eina_List *l, *l2;
320    E_Action_Group *actg;
321    E_Action_Description *actd;
322    int g, a;
323
324    evas_event_freeze(evas_object_evas_get(cfdata->gui.o_action_list));
325    edje_freeze();
326    e_widget_ilist_freeze(cfdata->gui.o_action_list);
327
328    e_widget_ilist_clear(cfdata->gui.o_action_list);
329    for (l = e_action_groups_get(), g = 0; l; l = l->next, g++)
330      {
331         actg = l->data;
332
333         if (!actg->acts) continue;
334
335         e_widget_ilist_header_append(cfdata->gui.o_action_list, NULL, _(actg->act_grp));
336
337         for (l2 = actg->acts, a = 0; l2; l2 = l2->next, a++)
338           {
339              actd = l2->data;
340
341              snprintf(buf, sizeof(buf), "%d %d", g, a);
342              e_widget_ilist_append(cfdata->gui.o_action_list, NULL, _(actd->act_name),
343                                    _action_change_cb, cfdata, buf);
344           }
345      }
346    e_widget_ilist_go(cfdata->gui.o_action_list);
347    e_widget_ilist_thaw(cfdata->gui.o_action_list);
348    edje_thaw();
349    evas_event_thaw(evas_object_evas_get(cfdata->gui.o_action_list));
350 }
351
352 /**************** Callbacks *********/
353
354 static void
355 _add_edge_binding_cb(void *data, void *data2 __UNUSED__)
356 {
357    E_Config_Dialog_Data *cfdata;
358
359    cfdata = data;
360
361    _auto_apply_changes(cfdata);
362
363    cfdata->locals.add = 1;
364    _edge_grab_wnd_show(cfdata);
365 }
366
367 static void
368 _modify_edge_binding_cb(void *data, void *data2 __UNUSED__)
369 {
370    E_Config_Dialog_Data *cfdata;
371
372    cfdata = data;
373
374    _auto_apply_changes(cfdata);
375
376    cfdata->locals.add = 0;
377    if (cfdata->locals.cur && cfdata->locals.cur[0])
378      {
379         E_Config_Binding_Edge *bi;
380         int n;
381
382         if (sscanf(cfdata->locals.cur, "e%d", &n) != 1)
383           return;
384
385         bi = eina_list_nth(cfdata->binding.edge, n);
386         cfdata->locals.edge = bi->edge;
387         cfdata->locals.drag_only = bi->drag_only;
388         cfdata->locals.delay = ((double)bi->delay);
389         if (bi->delay <= -1.0) cfdata->locals.click = 1, cfdata->locals.button = -bi->delay;
390         else cfdata->locals.click = 0, cfdata->locals.button = 0;
391         cfdata->locals.modifiers = bi->modifiers;
392      }
393    else return;
394    _edge_grab_wnd_show(cfdata);
395 }
396
397 static void
398 _binding_change_cb(void *data)
399 {
400    E_Config_Dialog_Data *cfdata;
401
402    cfdata = data;
403
404    _auto_apply_changes(cfdata);
405    if (cfdata->locals.cur) eina_stringshare_del(cfdata->locals.cur);
406    cfdata->locals.cur = NULL;
407
408    if ((!cfdata->locals.binding) || (!cfdata->locals.binding[0])) return;
409
410    cfdata->locals.cur = eina_stringshare_ref(cfdata->locals.binding);
411
412    _update_buttons(cfdata);
413    _update_action_list(cfdata);
414 }
415
416 static void
417 _action_change_cb(void *data)
418 {
419    E_Config_Dialog_Data *cfdata;
420
421    cfdata = data;
422    _update_action_params(cfdata);
423 }
424
425 static void
426 _delete_all_edge_binding_cb(void *data, void *data2 __UNUSED__)
427 {
428    E_Config_Binding_Edge *bi;
429    E_Config_Dialog_Data *cfdata;
430
431    cfdata = data;
432
433    EINA_LIST_FREE(cfdata->binding.edge, bi)
434      {
435         eina_stringshare_del(bi->action);
436         eina_stringshare_del(bi->params);
437         E_FREE(bi);
438      }
439
440    eina_stringshare_del(cfdata->locals.cur);
441    cfdata->locals.cur = NULL;
442
443    e_widget_ilist_clear(cfdata->gui.o_binding_list);
444    e_widget_ilist_go(cfdata->gui.o_binding_list);
445    e_widget_ilist_unselect(cfdata->gui.o_action_list);
446    e_widget_entry_clear(cfdata->gui.o_params);
447    e_widget_disabled_set(cfdata->gui.o_params, 1);
448    e_widget_label_text_set(cfdata->gui.o_button, NULL);
449
450    _update_buttons(cfdata);
451 }
452
453 static void
454 _delete_edge_binding_cb(void *data, void *data2 __UNUSED__)
455 {
456    Eina_List *l = NULL;
457    int sel, n;
458    E_Config_Dialog_Data *cfdata;
459    E_Config_Binding_Edge *bi;
460
461    cfdata = data;
462
463    sel = e_widget_ilist_selected_get(cfdata->gui.o_binding_list);
464    if (cfdata->locals.binding[0] == 'e')
465      {
466         if (sscanf(cfdata->locals.binding, "e%d", &n) != 1)
467           return;
468
469         l = eina_list_nth_list(cfdata->binding.edge, n);
470
471         if (l)
472           {
473              bi = eina_list_data_get(l);
474              eina_stringshare_del(bi->action);
475              eina_stringshare_del(bi->params);
476              E_FREE(bi);
477
478              cfdata->binding.edge = eina_list_remove_list(cfdata->binding.edge, l);
479           }
480      }
481
482    _update_edge_binding_list(cfdata);
483
484    if (sel >= e_widget_ilist_count(cfdata->gui.o_binding_list))
485      sel = e_widget_ilist_count(cfdata->gui.o_binding_list) - 1;
486
487    eina_stringshare_del(cfdata->locals.cur);
488    cfdata->locals.cur = NULL;
489
490    e_widget_ilist_selected_set(cfdata->gui.o_binding_list, sel);
491    if (sel < 0)
492      {
493         e_widget_ilist_unselect(cfdata->gui.o_action_list);
494         e_widget_entry_clear(cfdata->gui.o_params);
495         e_widget_disabled_set(cfdata->gui.o_params, 1);
496         e_widget_label_text_set(cfdata->gui.o_button, NULL);
497         _update_buttons(cfdata);
498      }
499 }
500
501 static void
502 _restore_edge_binding_defaults_cb(void *data, void *data2 __UNUSED__)
503 {
504    E_Config_Bindings *ecb;
505    Eina_Stringshare *prof;
506    E_Config_Dialog_Data *cfdata = data;
507
508    ecb = e_config_domain_system_load("e_bindings", e_config_descriptor_find("E_Config_Bindings"));
509    if (!ecb)
510      {
511         const char *type;
512
513         prof = eina_stringshare_ref(e_config_profile_get());
514         switch (e_config->config_type)
515           {
516            case E_CONFIG_PROFILE_TYPE_DESKTOP:
517              type = "standard";
518              break;
519            case E_CONFIG_PROFILE_TYPE_MOBILE:
520              type = "mobile";
521              break;
522            //case E_CONFIG_PROFILE_TYPE_TABLET: FIXME - not used
523            default:
524              type = "default";
525              break;
526           }
527         e_config_profile_set(type);
528         ecb = e_config_domain_system_load("e_bindings", e_config_descriptor_find("E_Config_Bindings"));
529         e_config_profile_set(prof);
530         eina_stringshare_del(prof);
531      }
532    if (!ecb) return;
533    E_FREE_LIST(cfdata->binding.edge, e_config_binding_edge_free);
534    cfdata->binding.edge = ecb->edge_bindings, ecb->edge_bindings = NULL;
535    e_config_bindings_free(ecb);
536
537    eina_stringshare_del(cfdata->locals.cur);
538    cfdata->locals.cur = NULL;
539
540    _update_edge_binding_list(cfdata);
541    _update_buttons(cfdata);
542
543    e_widget_ilist_unselect(cfdata->gui.o_action_list);
544    e_widget_entry_clear(cfdata->gui.o_params);
545    e_widget_disabled_set(cfdata->gui.o_params, 1);
546 }
547
548 /**************** Updates ***********/
549 static void
550 _update_action_list(E_Config_Dialog_Data *cfdata)
551 {
552    E_Config_Binding_Edge *bi;
553    int j = -1, i, n;
554    const char *action, *params;
555    char buf[256];
556
557    if (!cfdata->locals.cur) return;
558
559    if (cfdata->locals.cur[0] == 'e')
560      {
561         if (sscanf(cfdata->locals.cur, "e%d", &n) != 1)
562           return;
563
564         bi = eina_list_nth(cfdata->binding.edge, n);
565         if (!bi)
566           {
567              e_widget_ilist_unselect(cfdata->gui.o_action_list);
568              e_widget_entry_clear(cfdata->gui.o_params);
569              e_widget_disabled_set(cfdata->gui.o_params, 1);
570              return;
571           }
572         action = bi->action;
573         params = bi->params;
574      }
575    else
576      return;
577
578    _find_edge_binding_action(action, params, NULL, NULL, &j);
579
580    if (j >= 0)
581      {
582         for (i = 0; i < e_widget_ilist_count(cfdata->gui.o_action_list); i++)
583           {
584              if (i > j) break;
585              if (e_widget_ilist_nth_is_header(cfdata->gui.o_action_list, i)) j++;
586           }
587      }
588
589    if (j >= 0)
590      {
591         if (j == e_widget_ilist_selected_get(cfdata->gui.o_action_list))
592           _update_action_params(cfdata);
593         else
594           e_widget_ilist_selected_set(cfdata->gui.o_action_list, j);
595      }
596    else
597      {
598         e_widget_ilist_unselect(cfdata->gui.o_action_list);
599         eina_stringshare_del(cfdata->locals.action);
600         cfdata->locals.action = eina_stringshare_add("");
601         e_widget_entry_clear(cfdata->gui.o_params);
602         e_widget_label_text_set(cfdata->gui.o_button, NULL);
603      }
604    if (bi->delay < 0)
605      {
606         snprintf(buf, sizeof(buf), "%d", (int)-bi->delay);
607         e_widget_label_text_set(cfdata->gui.o_button, buf);
608      }
609    else
610      e_widget_label_text_set(cfdata->gui.o_button, NULL);
611
612    /*if (cfdata->locals.cur[0] == 'e')
613       {
614         sscanf(cfdata->locals.cur, "e%d", &n);
615         bi = eina_list_nth(cfdata->binding.edge, n);
616         if (!bi)
617           {
618              e_widget_ilist_unselect(cfdata->gui.o_action_list);
619              e_widget_entry_clear(cfdata->gui.o_params);
620              e_widget_disabled_set(cfdata->gui.o_params, 1);
621              return;
622           }
623
624         _find_edge_binding_action(bi, NULL, NULL, &j);
625         if (j >= 0)
626           {
627              for (i = 0; i < e_widget_ilist_count(cfdata->gui.o_action_list); i++)
628                {
629                   if (i > j) break;
630                   if (e_widget_ilist_nth_is_header(cfdata->gui.o_action_list, i)) j++;
631                }
632           }
633
634         if (j >= 0)
635           {
636              if (j == e_widget_ilist_selected_get(cfdata->gui.o_action_list))
637                _update_action_params(cfdata);
638              else
639                e_widget_ilist_selected_set(cfdata->gui.o_action_list, j);
640           }
641         else
642           {
643              e_widget_ilist_unselect(cfdata->gui.o_action_list);
644              free(cfdata->locals.action);
645              cfdata->locals.action = strdup("");
646              e_widget_entry_clear(cfdata->gui.o_params);
647           }
648       }*/
649 }
650
651 static void
652 _update_action_params(E_Config_Dialog_Data *cfdata)
653 {
654    int g, a, b;
655    E_Action_Group *actg;
656    E_Action_Description *actd;
657    E_Config_Binding_Edge *bi;
658    const char *action, *params;
659
660 #define EDGE_EXAMPLE_PARAMS                                         \
661   if ((!actd->param_example) || (!actd->param_example[0]))          \
662     e_widget_entry_text_set(cfdata->gui.o_params, TEXT_NO_PARAMS);  \
663   else                                                              \
664     e_widget_entry_text_set(cfdata->gui.o_params, actd->param_example)
665
666    if ((!cfdata->locals.action) || (!cfdata->locals.action[0]))
667      {
668         e_widget_disabled_set(cfdata->gui.o_params, 1);
669         e_widget_entry_clear(cfdata->gui.o_params);
670         return;
671      }
672    if (sscanf(cfdata->locals.action, "%d %d", &g, &a) != 2)
673      return;
674
675    actg = eina_list_nth(e_action_groups_get(), g);
676    if (!actg) return;
677    actd = eina_list_nth(actg->acts, a);
678    if (!actd) return;
679
680    if (actd->act_params)
681      {
682         e_widget_disabled_set(cfdata->gui.o_params, 1);
683         e_widget_entry_text_set(cfdata->gui.o_params, actd->act_params);
684         return;
685      }
686
687    if ((!cfdata->locals.cur) || (!cfdata->locals.cur[0]))
688      {
689         e_widget_disabled_set(cfdata->gui.o_params, 1);
690         EDGE_EXAMPLE_PARAMS;
691         return;
692      }
693
694    if (!actd->editable)
695      e_widget_disabled_set(cfdata->gui.o_params, 1);
696    else
697      e_widget_disabled_set(cfdata->gui.o_params, 0);
698
699    if (cfdata->locals.cur[0] == 'e')
700      {
701         if (sscanf(cfdata->locals.cur, "e%d", &b) != 1)
702           {
703              e_widget_disabled_set(cfdata->gui.o_params, 1);
704              EDGE_EXAMPLE_PARAMS;
705              return;
706           }
707
708         bi = eina_list_nth(cfdata->binding.edge, b);
709         if (!bi)
710           {
711              e_widget_disabled_set(cfdata->gui.o_params, 1);
712              EDGE_EXAMPLE_PARAMS;
713              return;
714           }
715         action = bi->action;
716         params = bi->params;
717      }
718    else
719      {
720         e_widget_disabled_set(cfdata->gui.o_params, 1);
721         EDGE_EXAMPLE_PARAMS;
722         return;
723      }
724
725    if (action)
726      {
727         if (!strcmp(action, actd->act_cmd))
728           {
729              if ((!params) || (!params[0]))
730                EDGE_EXAMPLE_PARAMS;
731              else
732                e_widget_entry_text_set(cfdata->gui.o_params, params);
733           }
734         else
735           EDGE_EXAMPLE_PARAMS;
736      }
737    else
738      EDGE_EXAMPLE_PARAMS;
739 }
740
741 static void
742 _update_edge_binding_list(E_Config_Dialog_Data *cfdata)
743 {
744    int i;
745    char *b, b2[64];
746    Eina_List *l;
747    E_Config_Binding_Edge *bi;
748
749    evas_event_freeze(evas_object_evas_get(cfdata->gui.o_binding_list));
750    edje_freeze();
751    e_widget_ilist_freeze(cfdata->gui.o_binding_list);
752
753    e_widget_ilist_clear(cfdata->gui.o_binding_list);
754    e_widget_ilist_go(cfdata->gui.o_binding_list);
755
756    if (cfdata->binding.edge)
757      {
758         cfdata->binding.edge = eina_list_sort(cfdata->binding.edge,
759                                               eina_list_count(cfdata->binding.edge), _edge_binding_sort_cb);
760      }
761
762    for (l = cfdata->binding.edge, i = 0; l; l = l->next, i++)
763      {
764         Evas_Object *ic;
765
766         bi = l->data;
767
768         b = _edge_binding_text_get(bi->edge, bi->delay, bi->modifiers);
769         if (!b) continue;
770
771         ic = edje_object_add(cfdata->evas);
772         e_util_edje_icon_set(ic, "enlightenment/edges");
773
774         snprintf(b2, sizeof(b2), "e%d", i);
775         e_widget_ilist_append(cfdata->gui.o_binding_list, ic, b,
776                               _binding_change_cb, cfdata, b2);
777         free(b);
778      }
779    e_widget_ilist_go(cfdata->gui.o_binding_list);
780
781    e_widget_ilist_thaw(cfdata->gui.o_binding_list);
782    edje_thaw();
783    evas_event_thaw(evas_object_evas_get(cfdata->gui.o_binding_list));
784
785    if (eina_list_count(cfdata->binding.edge))
786      e_widget_disabled_set(cfdata->gui.o_del_all, 0);
787    else
788      e_widget_disabled_set(cfdata->gui.o_del_all, 1);
789 }
790
791 static void
792 _update_buttons(E_Config_Dialog_Data *cfdata)
793 {
794    if (e_widget_ilist_count(cfdata->gui.o_binding_list))
795      e_widget_disabled_set(cfdata->gui.o_del_all, 0);
796    else
797      e_widget_disabled_set(cfdata->gui.o_del_all, 1);
798
799    if (!cfdata->locals.cur)
800      {
801         e_widget_disabled_set(cfdata->gui.o_mod, 1);
802         e_widget_disabled_set(cfdata->gui.o_del, 1);
803         return;
804      }
805    e_widget_disabled_set(cfdata->gui.o_mod, 0);
806    e_widget_disabled_set(cfdata->gui.o_del, 0);
807 }
808
809 /*************** Sorting *****************************/
810 static int
811 _edge_binding_sort_cb(const void *d1, const void *d2)
812 {
813    int i, j;
814    const E_Config_Binding_Edge *bi, *bi2;
815
816    bi = d1;
817    bi2 = d2;
818
819    i = 0; j = 0;
820    if (bi->modifiers & E_BINDING_MODIFIER_CTRL) i++;
821    if (bi->modifiers & E_BINDING_MODIFIER_ALT) i++;
822    if (bi->modifiers & E_BINDING_MODIFIER_SHIFT) i++;
823    if (bi->modifiers & E_BINDING_MODIFIER_WIN) i++;
824
825    if (bi2->modifiers & E_BINDING_MODIFIER_CTRL) j++;
826    if (bi2->modifiers & E_BINDING_MODIFIER_ALT) j++;
827    if (bi2->modifiers & E_BINDING_MODIFIER_SHIFT) j++;
828    if (bi2->modifiers & E_BINDING_MODIFIER_WIN) j++;
829
830    if (i < j) return -1;
831    else if (i > j)
832      return 1;
833
834    if (bi->modifiers < bi2->modifiers) return -1;
835    else if (bi->modifiers > bi2->modifiers)
836      return 1;
837
838    if (bi->edge < bi2->edge) return -1;
839    else if (bi->edge > bi2->edge)
840      return 1;
841
842    return 0;
843 }
844
845 /**************** grab window *******/
846 static void
847 _dia_del(void *data)
848 {
849    E_Config_Dialog_Data *cfdata;
850
851    cfdata = e_object_data_get(data);
852    if (!cfdata) return;
853    cfdata->locals.dia = NULL;
854 }
855
856 static void
857 _edge_grab_wnd_show(E_Config_Dialog_Data *cfdata)
858 {
859    Evas_Object *o, *obg, *os;
860    Evas *evas;
861    Evas_Coord minw, minh;
862    const char *bgfile;
863    int tw, th;
864    char *label = NULL;
865
866    if (cfdata->locals.dia != 0) return;
867
868    cfdata->locals.dia = e_dialog_normal_win_new(cfdata->cfd->dia->win, "E", "_edgebind_getedge_dialog");
869    if (!cfdata->locals.dia) return;
870    e_dialog_title_set(cfdata->locals.dia, _("Edge Binding Sequence"));
871    e_dialog_icon_set(cfdata->locals.dia, "enlightenment/edges", 48);
872    e_dialog_button_add(cfdata->locals.dia, _("Apply"), NULL, _edge_grab_wnd_cb_apply, cfdata);
873    e_dialog_button_add(cfdata->locals.dia, _("Close"), NULL, _edge_grab_wnd_cb_close, cfdata);
874    e_object_data_set(E_OBJECT(cfdata->locals.dia), cfdata);
875    e_object_del_attach_func_set(E_OBJECT(cfdata->locals.dia), _dia_del);
876    elm_win_center(cfdata->locals.dia->win, 1, 1);
877
878    evas = evas_object_evas_get(cfdata->locals.dia->win);
879
880    cfdata->gui.o_selector = o = edje_object_add(evas);
881    e_theme_edje_object_set(o, "base/theme/modules/conf_edgebindings",
882                            "e/modules/conf_edgebindings/selection");
883
884    cfdata->gui.o_slider = os = e_widget_slider_add(evas, 1, 0, _("%.2f seconds"), 0.0, 2.0, 0.05, 0, &(cfdata->locals.delay), NULL, 200);
885    edje_object_part_swallow(o, "e.swallow.slider", os);
886    e_widget_on_change_hook_set(os, _edge_grab_wnd_slider_changed_cb, cfdata);
887    evas_object_show(os);
888
889    cfdata->gui.o_check = os = e_widget_check_add(evas, _("Clickable edge"), &(cfdata->locals.click));
890    e_widget_size_min_resize(os);
891    e_widget_on_change_hook_set(os, _edge_grab_wnd_check_changed_cb, cfdata);
892    edje_object_part_box_append(o, "e.box", os);
893    evas_object_show(os);
894    e_widget_size_min_get(os, &minw, &minh);
895    evas_object_size_hint_min_set(os, minw, minh);
896
897    cfdata->gui.o_check2 = os = e_widget_check_add(evas, _("Drag only"), &(cfdata->locals.drag_only));
898    e_widget_size_min_resize(os);
899    e_widget_on_change_hook_set(os, _edge_grab_wnd_check_changed_cb, cfdata);
900    edje_object_part_box_append(o, "e.box", os);
901    evas_object_show(os);
902    e_widget_size_min_get(os, &minw, &minh);
903    evas_object_size_hint_min_set(os, minw, minh);
904
905    e_widget_disabled_set(cfdata->gui.o_slider, cfdata->locals.click);
906    e_widget_disabled_set(cfdata->gui.o_check2, cfdata->locals.click);
907    e_widget_disabled_set(cfdata->gui.o_check, cfdata->locals.drag_only);
908
909    edje_object_part_text_set(o, "e.text.description", TEXT_PRESS_EDGE_SEQUENCE);
910
911    edje_object_size_min_get(o, &minw, &minh);
912    if (!minw || !minh)
913      {
914         edje_object_calc_force(o);
915         edje_object_size_min_calc(o, &minw, &minh);
916      }
917
918    e_dialog_content_set(cfdata->locals.dia, o, minw, minh);
919
920    bgfile = e_bg_file_get(0, 0, 0, 0);
921    obg = e_thumb_icon_add(evas);
922    e_icon_fill_inside_set(obg, 0);
923    e_thumb_icon_file_set(obg, bgfile, "e/desktop/background");
924    eina_stringshare_del(bgfile);
925    edje_object_part_geometry_get(o, "e.swallow.background", NULL, NULL, &tw, &th);
926    e_thumb_icon_size_set(obg, tw, th);
927    edje_object_part_swallow(o, "e.swallow.background", obg);
928    e_thumb_icon_begin(obg);
929    evas_object_show(obg);
930
931    if (cfdata->locals.edge)
932      {
933         label = _edge_binding_text_get(cfdata->locals.edge, ((float)cfdata->locals.delay), cfdata->locals.modifiers);
934         edje_object_part_text_set(cfdata->gui.o_selector, "e.text.selection", label);
935         E_FREE(label);
936      }
937
938    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
939                                   _edge_grab_wnd_selected_edge_cb, cfdata);
940    e_dialog_show(cfdata->locals.dia);
941 }
942
943 static void
944 _edge_grab_wnd_hide(E_Config_Dialog_Data *cfdata)
945 {
946    e_object_del(E_OBJECT(cfdata->locals.dia));
947    cfdata->locals.dia = NULL;
948 }
949
950 static void
951 _edge_grab_wnd_cb_apply(void *data, E_Dialog *dia __UNUSED__)
952 {
953    E_Config_Dialog_Data *cfdata;
954
955    cfdata = data;
956    if (!cfdata->locals.edge) return;
957    _edge_grab_wnd_selection_apply(cfdata);
958    _edge_grab_wnd_hide(cfdata);
959 }
960
961 static void
962 _edge_grab_wnd_cb_close(void *data, E_Dialog *dia __UNUSED__)
963 {
964    E_Config_Dialog_Data *cfdata;
965
966    cfdata = data;
967    _edge_grab_wnd_hide(cfdata);
968 }
969
970 static void
971 _edge_grab_wnd_slider_changed_cb(void *data, Evas_Object *obj __UNUSED__)
972 {
973    E_Config_Dialog_Data *cfdata = data;
974    char *label = NULL;
975
976    if (!cfdata->locals.edge) return;
977    label = _edge_binding_text_get(cfdata->locals.edge,
978                                   ((float)cfdata->locals.delay),
979                                   cfdata->locals.modifiers);
980    edje_object_part_text_set(cfdata->gui.o_selector, "e.text.selection", label);
981    E_FREE(label);
982 }
983
984 static void
985 _edge_grab_wnd_check_changed_cb(void *data, Evas_Object *obj __UNUSED__)
986 {
987    E_Config_Dialog_Data *cfdata = data;
988    char *label = NULL;
989
990    if (cfdata->locals.click)
991      {
992         if (cfdata->locals.edge && cfdata->locals.button)
993           label = _edge_binding_text_get(cfdata->locals.edge, -1.0 * cfdata->locals.button, cfdata->locals.modifiers);
994      }
995    else
996      {
997         if (cfdata->locals.edge)
998           label = _edge_binding_text_get(cfdata->locals.edge, ((float)cfdata->locals.delay), cfdata->locals.modifiers);
999         e_widget_disabled_set(cfdata->gui.o_slider, 0);
1000      }
1001    e_widget_disabled_set(cfdata->gui.o_slider, cfdata->locals.click);
1002    e_widget_disabled_set(cfdata->gui.o_check2, cfdata->locals.click);
1003    e_widget_disabled_set(cfdata->gui.o_check, cfdata->locals.drag_only);
1004
1005    edje_object_part_text_set(cfdata->gui.o_selector, "e.text.selection", label);
1006    E_FREE(label);
1007 }
1008
1009 static void
1010 _edge_grab_wnd_selected_edge_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1011 {
1012    Evas_Event_Mouse_Down *event;
1013    E_Config_Dialog_Data *cfdata;
1014    E_Zone_Edge edge;
1015    Evas_Coord xx, yy, x, y, w, h;
1016    char *label;
1017
1018    if (!(cfdata = data)) return;
1019    if (!(event = event_info)) return;
1020    cfdata->locals.button = event->button;
1021
1022    evas_object_geometry_get(cfdata->gui.o_selector, &xx, &yy, NULL, NULL);
1023    edje_object_part_geometry_get(cfdata->gui.o_selector, "e.edge.top_left", &x, &y, &w, &h);
1024    if (E_INSIDE(event->canvas.x, event->canvas.y, x + xx, y + yy, w, h))
1025      {
1026         edge = E_ZONE_EDGE_TOP_LEFT;
1027         goto stop;
1028      }
1029    edje_object_part_geometry_get(cfdata->gui.o_selector, "e.edge.top", &x, &y, &w, &h);
1030    if (E_INSIDE(event->canvas.x, event->canvas.y, x + xx, y + yy, w, h))
1031      {
1032         edge = E_ZONE_EDGE_TOP;
1033         goto stop;
1034      }
1035    edje_object_part_geometry_get(cfdata->gui.o_selector, "e.edge.top_right", &x, &y, &w, &h);
1036    if (E_INSIDE(event->canvas.x, event->canvas.y, x + xx, y + yy, w, h))
1037      {
1038         edge = E_ZONE_EDGE_TOP_RIGHT;
1039         goto stop;
1040      }
1041    edje_object_part_geometry_get(cfdata->gui.o_selector, "e.edge.right", &x, &y, &w, &h);
1042    if (E_INSIDE(event->canvas.x, event->canvas.y, x + xx, y + yy, w, h))
1043      {
1044         edge = E_ZONE_EDGE_RIGHT;
1045         goto stop;
1046      }
1047    edje_object_part_geometry_get(cfdata->gui.o_selector, "e.edge.bottom_right", &x, &y, &w, &h);
1048    if (E_INSIDE(event->canvas.x, event->canvas.y, x + xx, y + yy, w, h))
1049      {
1050         edge = E_ZONE_EDGE_BOTTOM_RIGHT;
1051         goto stop;
1052      }
1053    edje_object_part_geometry_get(cfdata->gui.o_selector, "e.edge.bottom", &x, &y, &w, &h);
1054    if (E_INSIDE(event->canvas.x, event->canvas.y, x + xx, y + yy, w, h))
1055      {
1056         edge = E_ZONE_EDGE_BOTTOM;
1057         goto stop;
1058      }
1059    edje_object_part_geometry_get(cfdata->gui.o_selector, "e.edge.bottom_left", &x, &y, &w, &h);
1060    if (E_INSIDE(event->canvas.x, event->canvas.y, x + xx, y + yy, w, h))
1061      {
1062         edge = E_ZONE_EDGE_BOTTOM_LEFT;
1063         goto stop;
1064      }
1065    edje_object_part_geometry_get(cfdata->gui.o_selector, "e.edge.left", &x, &y, &w, &h);
1066    if (E_INSIDE(event->canvas.x, event->canvas.y, x + xx, y + yy, w, h))
1067      {
1068         edge = E_ZONE_EDGE_LEFT;
1069         goto stop;
1070      }
1071    return;
1072
1073 stop:
1074    cfdata->locals.edge = edge;
1075    cfdata->locals.modifiers = 0;
1076
1077    if (evas_key_modifier_is_set(event->modifiers, "Control"))
1078      cfdata->locals.modifiers |= E_BINDING_MODIFIER_CTRL;
1079    if (evas_key_modifier_is_set(event->modifiers, "Shift"))
1080      cfdata->locals.modifiers |= E_BINDING_MODIFIER_SHIFT;
1081    if (evas_key_modifier_is_set(event->modifiers, "Alt"))
1082      cfdata->locals.modifiers |= E_BINDING_MODIFIER_ALT;
1083    if (evas_key_modifier_is_set(event->modifiers, "Win"))
1084      cfdata->locals.modifiers |= E_BINDING_MODIFIER_WIN;
1085
1086    label = _edge_binding_text_get(cfdata->locals.edge,
1087                                   cfdata->locals.click ? (-1.0 * cfdata->locals.button) : ((float)cfdata->locals.delay),
1088                                   cfdata->locals.modifiers);
1089    edje_object_part_text_set(cfdata->gui.o_selector, "e.text.selection", label);
1090    E_FREE(label);
1091 }
1092
1093 static void
1094 _edge_grab_wnd_selection_apply(E_Config_Dialog_Data *cfdata)
1095 {
1096    E_Config_Binding_Edge *bi = NULL, *bi2 = NULL;
1097    Eina_List *l;
1098    int found = 0, n = -1;
1099
1100    if (cfdata->locals.click) cfdata->locals.delay = -1.0 * cfdata->locals.button;
1101    else if (cfdata->locals.delay < 0)
1102      cfdata->locals.delay = 0;
1103    if (cfdata->locals.add)
1104      {
1105         EINA_LIST_FOREACH(cfdata->binding.edge, l, bi)
1106           if ((bi->modifiers == cfdata->locals.modifiers) &&
1107               (bi->edge == cfdata->locals.edge) &&
1108               (bi->drag_only == cfdata->locals.drag_only) &&
1109               ((bi->delay * 1000) == (cfdata->locals.delay * 1000)))
1110             {
1111                found = 1;
1112                break;
1113             }
1114      }
1115    else
1116      {
1117         if (cfdata->locals.cur && cfdata->locals.cur[0] &&
1118             (sscanf(cfdata->locals.cur, "e%d", &n) == 1))
1119           {
1120              bi = eina_list_nth(cfdata->binding.edge, n);
1121              EINA_LIST_FOREACH(cfdata->binding.edge, l, bi2)
1122                {
1123                   if (bi == bi2) continue;
1124                   if ((bi->modifiers == cfdata->locals.modifiers) &&
1125                       (bi->edge == cfdata->locals.edge) &&
1126                       (bi->drag_only == cfdata->locals.drag_only) &&
1127                       ((bi->delay * 1000) == (cfdata->locals.delay * 1000)))
1128                     {
1129                        found = 1;
1130                        break;
1131                     }
1132                }
1133           }
1134      }
1135
1136    if (!found)
1137      {
1138         if (cfdata->locals.add)
1139           {
1140              bi = E_NEW(E_Config_Binding_Edge, 1);
1141              bi->context = E_BINDING_CONTEXT_ZONE;
1142              bi->edge = cfdata->locals.edge;
1143              bi->any_mod = 0;
1144              bi->delay = (float)(cfdata->locals.delay);
1145              bi->action = NULL;
1146              bi->params = NULL;
1147              bi->modifiers = cfdata->locals.modifiers;
1148              bi->drag_only = cfdata->locals.drag_only;
1149              cfdata->binding.edge = eina_list_append(cfdata->binding.edge, bi);
1150           }
1151         else
1152           {
1153              if (cfdata->locals.cur && cfdata->locals.cur[0] &&
1154                  (sscanf(cfdata->locals.cur, "e%d", &n) == 1))
1155                {
1156                   bi = eina_list_nth(cfdata->binding.edge, n);
1157
1158                   bi->modifiers = cfdata->locals.modifiers;
1159                   bi->delay = cfdata->locals.delay;
1160                   bi->edge = cfdata->locals.edge;
1161                   bi->drag_only = cfdata->locals.drag_only;
1162                }
1163           }
1164
1165         if (cfdata->locals.add)
1166           {
1167              E_Config_Binding_Edge *tmp;
1168              char buf[256];
1169
1170              n = 0;
1171              _update_edge_binding_list(cfdata);
1172              EINA_LIST_FOREACH(cfdata->binding.edge, l, tmp)
1173                {
1174                   if (tmp == bi) break;
1175                   n++;
1176                }
1177              e_widget_ilist_selected_set(cfdata->gui.o_binding_list, n);
1178              e_widget_ilist_unselect(cfdata->gui.o_action_list);
1179              eina_stringshare_del(cfdata->locals.action);
1180              cfdata->locals.action = eina_stringshare_add("");
1181              snprintf(buf, sizeof(buf), "%d", (int)-bi->delay);
1182              e_widget_label_text_set(cfdata->gui.o_button, NULL);
1183              if ((cfdata->params) && (cfdata->params[0]))
1184                {
1185                   int j, g = -1;
1186                   _find_edge_binding_action("exec", NULL, &g, NULL, &j);
1187                   if (j >= 0)
1188                     {
1189                        e_widget_ilist_unselect(cfdata->gui.o_action_list);
1190                        e_widget_ilist_selected_set(cfdata->gui.o_action_list, (j + g + 1));
1191                        e_widget_entry_clear(cfdata->gui.o_params);
1192                        e_widget_entry_text_set(cfdata->gui.o_params, cfdata->params);
1193                     }
1194                }
1195              else
1196                {
1197                   e_widget_entry_clear(cfdata->gui.o_params);
1198                   e_widget_disabled_set(cfdata->gui.o_params, 1);
1199                }
1200           }
1201         else if (bi)
1202           {
1203              char *label;
1204
1205              label = _edge_binding_text_get(bi->edge, bi->delay, bi->modifiers);
1206              e_widget_ilist_nth_label_set(cfdata->gui.o_binding_list, n, label);
1207              free(label);
1208           }
1209      }
1210    else
1211      {
1212         int g, a, j;
1213         const char *label = NULL;
1214         E_Action_Group *actg = NULL;
1215         E_Action_Description *actd = NULL;
1216
1217         if (cfdata->locals.add)
1218           _find_edge_binding_action(bi->action, bi->params, &g, &a, &j);
1219         else
1220           _find_edge_binding_action(bi2->action, bi2->params, &g, &a, &j);
1221
1222         actg = eina_list_nth(e_action_groups_get(), g);
1223         if (actg) actd = eina_list_nth(actg->acts, a);
1224
1225         if (actd) label = _(actd->act_name);
1226
1227         e_util_dialog_show(_("Edge Binding Error"),
1228                            _("The edge binding that you chose is already used by<br>"
1229                              "<hilight>%s</hilight> action.<br>"
1230                              "Please choose another edge to bind."),
1231                            label ? label : _("Unknown"));
1232      }
1233 }
1234
1235 /********** Helper *********************************/
1236 static void
1237 _auto_apply_changes(E_Config_Dialog_Data *cfdata)
1238 {
1239    int n, g, a, ok;
1240    E_Config_Binding_Edge *bi;
1241    E_Action_Group *actg;
1242    E_Action_Description *actd;
1243
1244    if ((!cfdata->locals.cur) || (!cfdata->locals.cur[0]) ||
1245        (!cfdata->locals.action) || (!cfdata->locals.action[0])) return;
1246
1247    if (sscanf(cfdata->locals.cur, "e%d", &n) != 1)
1248      return;
1249    if (sscanf(cfdata->locals.action, "%d %d", &g, &a) != 2)
1250      return;
1251
1252    bi = eina_list_nth(cfdata->binding.edge, n);
1253    if (!bi) return;
1254
1255    actg = eina_list_nth(e_action_groups_get(), g);
1256    if (!actg) return;
1257    actd = eina_list_nth(actg->acts, a);
1258    if (!actd) return;
1259
1260    eina_stringshare_del(bi->action);
1261    bi->action = NULL;
1262
1263    if (actd->act_cmd) bi->action = eina_stringshare_add(actd->act_cmd);
1264
1265    eina_stringshare_del(bi->params);
1266    bi->params = NULL;
1267
1268    if (actd->act_params)
1269      bi->params = eina_stringshare_add(actd->act_params);
1270    else
1271      {
1272         ok = 1;
1273         if (cfdata->locals.params)
1274           {
1275              if (!strcmp(cfdata->locals.params, TEXT_NO_PARAMS))
1276                ok = 0;
1277
1278              if ((actd->param_example) && (!strcmp(cfdata->locals.params, actd->param_example)))
1279                ok = 0;
1280           }
1281         else
1282           ok = 0;
1283
1284         if (ok)
1285           bi->params = eina_stringshare_add(cfdata->locals.params);
1286      }
1287 }
1288
1289 static void
1290 _find_edge_binding_action(const char *action, const char *params, int *g, int *a, int *n)
1291 {
1292    Eina_List *l, *l2;
1293    int gg = -1, aa = -1, nn = -1, found;
1294    E_Action_Group *actg;
1295    E_Action_Description *actd;
1296
1297    if (g) *g = -1;
1298    if (a) *a = -1;
1299    if (n) *n = -1;
1300
1301    found = 0;
1302    for (l = e_action_groups_get(), gg = 0, nn = 0; l; l = l->next, gg++)
1303      {
1304         actg = l->data;
1305
1306         for (l2 = actg->acts, aa = 0; l2; l2 = l2->next, aa++)
1307           {
1308              actd = l2->data;
1309              if (!strcmp((!action ? "" : action), (!actd->act_cmd ? "" : actd->act_cmd)))
1310                {
1311                   if (!params || !params[0])
1312                     {
1313                        if ((!actd->act_params) || (!actd->act_params[0]))
1314                          {
1315                             if (g) *g = gg;
1316                             if (a) *a = aa;
1317                             if (n) *n = nn;
1318                             return;
1319                          }
1320                        else
1321                          continue;
1322                     }
1323                   else
1324                     {
1325                        if ((!actd->act_params) || (!actd->act_params[0]))
1326                          {
1327                             if (g) *g = gg;
1328                             if (a) *a = aa;
1329                             if (n) *n = nn;
1330                             found = 1;
1331                          }
1332                        else
1333                          {
1334                             if (!strcmp(params, actd->act_params))
1335                               {
1336                                  if (g) *g = gg;
1337                                  if (a) *a = aa;
1338                                  if (n) *n = nn;
1339                                  return;
1340                               }
1341                          }
1342                     }
1343                }
1344              nn++;
1345           }
1346         if (found) break;
1347      }
1348
1349    if (!found)
1350      {
1351         if (g) *g = -1;
1352         if (a) *a = -1;
1353         if (n) *n = -1;
1354      }
1355 }
1356
1357 static char *
1358 _edge_binding_text_get(E_Zone_Edge edge, float delay, int mod)
1359 {
1360    char b[256] = "";
1361
1362    if (mod & E_BINDING_MODIFIER_CTRL)
1363      strcat(b, _("CTRL"));
1364
1365    if (mod & E_BINDING_MODIFIER_ALT)
1366      {
1367         if (b[0]) strcat(b, " + ");
1368         strcat(b, _("ALT"));
1369      }
1370
1371    if (mod & E_BINDING_MODIFIER_SHIFT)
1372      {
1373         if (b[0]) strcat(b, " + ");
1374         strcat(b, _("SHIFT"));
1375      }
1376
1377    if (mod & E_BINDING_MODIFIER_WIN)
1378      {
1379         if (b[0]) strcat(b, " + ");
1380         strcat(b, _("WIN"));
1381      }
1382
1383    if (edge)
1384      {
1385         if (b[0]) strcat(b, " + ");
1386
1387         switch (edge)
1388           {
1389            case E_ZONE_EDGE_LEFT:
1390              strcat(b, _("Left Edge"));
1391              break;
1392
1393            case E_ZONE_EDGE_TOP:
1394              strcat(b, _("Top Edge"));
1395              break;
1396
1397            case E_ZONE_EDGE_RIGHT:
1398              strcat(b, _("Right Edge"));
1399              break;
1400
1401            case E_ZONE_EDGE_BOTTOM:
1402              strcat(b, _("Bottom Edge"));
1403              break;
1404
1405            case E_ZONE_EDGE_TOP_LEFT:
1406              strcat(b, _("Top Left Edge"));
1407              break;
1408
1409            case E_ZONE_EDGE_TOP_RIGHT:
1410              strcat(b, _("Top Right Edge"));
1411              break;
1412
1413            case E_ZONE_EDGE_BOTTOM_RIGHT:
1414              strcat(b, _("Bottom Right Edge"));
1415              break;
1416
1417            case E_ZONE_EDGE_BOTTOM_LEFT:
1418              strcat(b, _("Bottom Left Edge"));
1419              break;
1420
1421            default:
1422              break;
1423           }
1424      }
1425
1426    if (delay)
1427      {
1428         char buf[20];
1429
1430         if (b[0]) strcat(b, " ");
1431         if (delay == -1.0)
1432           snprintf(buf, 20, _("(left clickable)"));
1433         else if (delay < -1.0)
1434           snprintf(buf, 20, _("(clickable)"));
1435         else
1436           snprintf(buf, 20, "%.2fs", delay);
1437         strcat(b, buf);
1438      }
1439
1440    if (!b[0]) return strdup(TEXT_NONE_ACTION_EDGE);
1441    return strdup(b);
1442 }
1443