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