Tizen 2.1 release
[platform/core/uifw/e17.git] / src / modules / conf_applications / e_int_config_apps.c
1 #include "e.h"
2
3 typedef struct _E_Config_Data
4 {
5    const char *title, *icon, *dialog, *filename;
6    Eina_Bool   show_autostart;
7 } E_Config_Data;
8
9 typedef struct _E_Config_App_List
10 {
11    E_Config_Dialog_Data *cfdata;
12    Evas_Object          *o_list, *o_add, *o_del, *o_desc;
13    Eina_List            *desks;
14 } E_Config_App_List;
15
16 struct _E_Config_Dialog_Data
17 {
18    E_Config_Data    *data;
19    Evas_Object      *o_list, *o_up, *o_down, *o_del;
20    Eina_List        *apps;
21    Ecore_Timer      *fill_delay;
22    E_Config_App_List apps_user;
23    E_Config_App_List apps_xdg; /* xdg autostart apps */
24 };
25
26 /* local function prototypes */
27 static E_Config_Dialog *_create_dialog(E_Container *con, E_Config_Data *data);
28 static void            *_create_data(E_Config_Dialog *cfd);
29 static void             _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata);
30 static Evas_Object     *_basic_create(E_Config_Dialog *cfd __UNUSED__, Evas *evas, E_Config_Dialog_Data *cfdata);
31 static int              _basic_apply(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata);
32 static Eina_List       *_load_menu(const char *path);
33 static Eina_List       *_load_order(const char *path);
34 static int              _save_menu(E_Config_Dialog_Data *cfdata);
35 static int              _save_order(E_Config_Dialog_Data *cfdata);
36 static void             _fill_apps_list(E_Config_App_List *apps);
37 static void             _fill_xdg_list(E_Config_App_List *apps);
38 static void             _fill_order_list(E_Config_Dialog_Data *cfdata);
39 static void             _cb_apps_list_selected(void *data);
40 static void             _cb_order_list_selected(void *data);
41 static int              _cb_desks_sort(const void *data1, const void *data2);
42 static int              _cb_desks_name(const void *data1, const void *data2);
43 static int              _cb_desks_sort(const void *data1, const void *data2);
44 static void             _cb_add(void *data, void *data2 __UNUSED__);
45 static void             _cb_del(void *data, void *data2 __UNUSED__);
46 static void             _cb_up(void *data, void *data2 __UNUSED__);
47 static void             _cb_down(void *data, void *data2 __UNUSED__);
48 static void             _cb_order_del(void *data, void *data2 __UNUSED__);
49 static Eina_Bool        _cb_fill_delay(void *data);
50 static void             _list_items_state_set(E_Config_App_List *apps);
51
52 E_Config_Dialog *
53 e_int_config_apps_add(E_Container *con, const char *params __UNUSED__)
54 {
55    E_Desktop_Edit *ed;
56
57    if (!(ed = e_desktop_edit(con, NULL))) return NULL;
58    return ed->cfd;
59 }
60
61 E_Config_Dialog *
62 e_int_config_apps_favs(E_Container *con, const char *params __UNUSED__)
63 {
64    E_Config_Data *data;
65    char buff[PATH_MAX];
66
67    e_user_dir_concat_static(buff, "applications/menu/favorite.menu");
68    data = E_NEW(E_Config_Data, 1);
69    data->title = eina_stringshare_add(_("Favorite Applications"));
70    data->dialog = eina_stringshare_add("menus/favorites_menu");
71    data->icon = eina_stringshare_add("user-bookmarks");
72    data->filename = eina_stringshare_add(buff);
73    return _create_dialog(con, data);
74 }
75
76 E_Config_Dialog *
77 e_int_config_apps_ibar(E_Container *con, const char *params __UNUSED__)
78 {
79    E_Config_Data *data;
80    char buff[PATH_MAX];
81
82    e_user_dir_concat_static(buff, "applications/bar/default/.order");
83    data = E_NEW(E_Config_Data, 1);
84    data->title = eina_stringshare_add(_("IBar Applications"));
85    data->dialog = eina_stringshare_add("applications/ibar_applications");
86    data->icon = eina_stringshare_add("preferences-applications-ibar");
87    data->filename = eina_stringshare_add(buff);
88    return _create_dialog(con, data);
89 }
90
91 E_Config_Dialog *
92 e_int_config_apps_ibar_other(E_Container *con, const char *path)
93 {
94    E_Config_Data *data;
95
96    if (!path) return NULL;
97    data = E_NEW(E_Config_Data, 1);
98    data->title = eina_stringshare_add(_("IBar Applications"));
99    data->dialog = eina_stringshare_add("internal/ibar_other");
100    data->icon = eina_stringshare_add("preferences-applications-ibar");
101    data->filename = eina_stringshare_add(path);
102    return _create_dialog(con, data);
103 }
104
105 E_Config_Dialog *
106 e_int_config_apps_startup(E_Container *con, const char *params __UNUSED__)
107 {
108    E_Config_Data *data;
109    char buff[PATH_MAX];
110
111    e_user_dir_concat_static(buff, "applications/startup/.order");
112    data = E_NEW(E_Config_Data, 1);
113    data->title = eina_stringshare_add(_("Startup Applications"));
114    data->dialog = eina_stringshare_add("applications/startup_applications");
115    data->icon = eina_stringshare_add("preferences-applications-startup");
116    data->filename = eina_stringshare_add(buff);
117    data->show_autostart = EINA_TRUE;
118    return _create_dialog(con, data);
119 }
120
121 E_Config_Dialog *
122 e_int_config_apps_restart(E_Container *con, const char *params __UNUSED__)
123 {
124    E_Config_Data *data;
125    char buff[PATH_MAX];
126
127    e_user_dir_concat_static(buff, "applications/restart/.order");
128    data = E_NEW(E_Config_Data, 1);
129    data->title = eina_stringshare_add(_("Restart Applications"));
130    data->dialog = eina_stringshare_add("applications/restart_applications");
131    data->icon = eina_stringshare_add("preferences-applications-restart");
132    data->filename = eina_stringshare_add(buff);
133    return _create_dialog(con, data);
134 }
135
136 E_Config_Dialog *
137 e_int_config_apps_desk_lock(E_Container *con, const char *params __UNUSED__)
138 {
139    E_Config_Data *data;
140    char buff[PATH_MAX];
141
142    e_user_dir_concat_static(buff, "applications/screen-lock/.order");
143    data = E_NEW(E_Config_Data, 1);
144    data->title = eina_stringshare_add(_("Screen Lock Applications"));
145    data->dialog = eina_stringshare_add("applications/screen_lock_applications");
146    data->icon = eina_stringshare_add("preferences-applications-screen-lock");
147    data->filename = eina_stringshare_add(buff);
148    return _create_dialog(con, data);
149 }
150
151 E_Config_Dialog *
152 e_int_config_apps_desk_unlock(E_Container *con, const char *params __UNUSED__)
153 {
154    E_Config_Data *data;
155    char buff[PATH_MAX];
156
157    e_user_dir_concat_static(buff, "applications/screen-unlock/.order");
158    data = E_NEW(E_Config_Data, 1);
159    data->title = eina_stringshare_add(_("Screen Unlock Applications"));
160    data->dialog = eina_stringshare_add("applications/screen_unlock_applications");
161    data->icon = eina_stringshare_add("preferences-applications-screen-unlock");
162    data->filename = eina_stringshare_add(buff);
163    return _create_dialog(con, data);
164 }
165
166 /* local function prototypes */
167 static E_Config_Dialog *
168 _create_dialog(E_Container *con, E_Config_Data *data)
169 {
170    E_Config_Dialog *cfd;
171    E_Config_Dialog_View *v;
172
173    if (e_config_dialog_find("E", data->dialog))
174      {
175         if (data->title) eina_stringshare_del(data->title);
176         if (data->dialog) eina_stringshare_del(data->dialog);
177         if (data->icon) eina_stringshare_del(data->icon);
178         if (data->filename) eina_stringshare_del(data->filename);
179         E_FREE(data);
180         return NULL;
181      }
182
183    v = E_NEW(E_Config_Dialog_View, 1);
184    v->create_cfdata = _create_data;
185    v->free_cfdata = _free_data;
186    v->basic.create_widgets = _basic_create;
187    v->basic.apply_cfdata = _basic_apply;
188
189    cfd = e_config_dialog_new(con, data->title, "E", data->dialog,
190                              data->icon, 0, v, data);
191    return cfd;
192 }
193
194 static void *
195 _create_data(E_Config_Dialog *cfd)
196 {
197    E_Config_Dialog_Data *cfdata;
198    E_Config_Data *data;
199    const char *ext;
200
201    if (!(data = cfd->data)) return NULL;
202    if (!data->filename) return NULL;
203    if (!(ext = strrchr(data->filename, '.'))) return NULL;
204
205    cfdata = E_NEW(E_Config_Dialog_Data, 1);
206    cfdata->data = data;
207    cfdata->apps_xdg.cfdata = cfdata;
208    cfdata->apps_user.cfdata = cfdata;
209    if (!strcmp(ext, ".menu"))
210      cfdata->apps = _load_menu(data->filename);
211    else if (!strcmp(ext, ".order"))
212      cfdata->apps = _load_order(data->filename);
213
214    return cfdata;
215 }
216
217 static void
218 _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
219 {
220    E_Config_Data *data;
221    Efreet_Desktop *desk;
222
223    if (cfdata->fill_delay) ecore_timer_del(cfdata->fill_delay);
224
225    if ((data = cfdata->data))
226      {
227         if (data->title) eina_stringshare_del(data->title);
228         if (data->dialog) eina_stringshare_del(data->dialog);
229         if (data->icon) eina_stringshare_del(data->icon);
230         if (data->filename) eina_stringshare_del(data->filename);
231         E_FREE(data);
232      }
233    EINA_LIST_FREE(cfdata->apps, desk)
234      efreet_desktop_free(desk);
235    EINA_LIST_FREE(cfdata->apps_user.desks, desk)
236      efreet_desktop_free(desk);
237    EINA_LIST_FREE(cfdata->apps_xdg.desks, desk)
238      efreet_desktop_free(desk);
239    E_FREE(cfdata);
240 }
241
242 static Evas_Object *
243 _basic_create(E_Config_Dialog *cfd __UNUSED__, Evas *evas, E_Config_Dialog_Data *cfdata)
244 {
245    Evas_Object *otb, *ot;
246    int mw;
247
248    otb = e_widget_toolbook_add(evas, 24, 24);
249
250    if (cfdata->data->show_autostart)
251      {
252         /* XDG autostart page */
253         ot = e_widget_table_add(evas, EINA_FALSE);
254         cfdata->apps_xdg.o_list = e_widget_ilist_add(evas, 24, 24, NULL);
255         e_widget_ilist_multi_select_set(cfdata->apps_xdg.o_list, EINA_TRUE);
256         e_widget_size_min_get(cfdata->apps_xdg.o_list, &mw, NULL);
257         if (mw < (200 * e_scale)) mw = (200 * e_scale);
258         e_widget_size_min_set(cfdata->apps_xdg.o_list, mw, (75 * e_scale));
259         e_widget_table_object_append(ot, cfdata->apps_xdg.o_list, 0, 0, 2, 1, 1, 1, 1, 1);
260
261         cfdata->apps_xdg.o_desc = e_widget_textblock_add(evas);
262         e_widget_size_min_set(cfdata->apps_xdg.o_desc, 100, (45 * e_scale));
263         e_widget_table_object_append(ot, cfdata->apps_xdg.o_desc, 0, 1, 2, 1, 1, 1, 0, 0);
264
265         cfdata->apps_xdg.o_add = e_widget_button_add(evas, _("Add"), "list-add",
266                                                      _cb_add, &cfdata->apps_xdg, NULL);
267         e_widget_disabled_set(cfdata->apps_xdg.o_add, EINA_TRUE);
268         e_widget_table_object_append(ot, cfdata->apps_xdg.o_add, 0, 2, 1, 1, 1, 1, 1, 0);
269         cfdata->apps_xdg.o_del = e_widget_button_add(evas, _("Remove"), "list-remove",
270                                                      _cb_del, &cfdata->apps_xdg, NULL);
271         e_widget_disabled_set(cfdata->apps_xdg.o_del, EINA_TRUE);
272         e_widget_table_object_append(ot, cfdata->apps_xdg.o_del, 1, 2, 1, 1, 1, 1, 1, 0);
273
274         e_widget_toolbook_page_append(otb, NULL, _("System"), ot,
275                                       1, 1, 1, 1, 0.5, 0.0);
276      }
277
278    /* Selection page */
279    ot = e_widget_table_add(evas, EINA_FALSE);
280    cfdata->apps_user.o_list = e_widget_ilist_add(evas, 24, 24, NULL);
281    e_widget_ilist_multi_select_set(cfdata->apps_user.o_list, EINA_TRUE);
282    e_widget_size_min_get(cfdata->apps_user.o_list, &mw, NULL);
283    if (mw < (200 * e_scale)) mw = (200 * e_scale);
284    e_widget_size_min_set(cfdata->apps_user.o_list, mw, (75 * e_scale));
285    e_widget_table_object_append(ot, cfdata->apps_user.o_list, 0, 0, 2, 1, 1, 1, 1, 1);
286    cfdata->apps_user.o_add = e_widget_button_add(evas, _("Add"), "list-add",
287                                                  _cb_add, &cfdata->apps_user, NULL);
288    e_widget_disabled_set(cfdata->apps_user.o_add, EINA_TRUE);
289    e_widget_table_object_append(ot, cfdata->apps_user.o_add, 0, 1, 1, 1, 1, 1, 1, 0);
290    cfdata->apps_user.o_del = e_widget_button_add(evas, _("Remove"), "list-remove",
291                                                  _cb_del, &cfdata->apps_user, NULL);
292    e_widget_disabled_set(cfdata->apps_user.o_del, EINA_TRUE);
293    e_widget_table_object_append(ot, cfdata->apps_user.o_del, 1, 1, 1, 1, 1, 1, 1, 0);
294    e_widget_toolbook_page_append(otb, NULL, _("Applications"), ot,
295                                  1, 1, 1, 1, 0.5, 0.0);
296
297    /* Order page */
298    ot = e_widget_table_add(evas, EINA_FALSE);
299    cfdata->o_list = e_widget_ilist_add(evas, 24, 24, NULL);
300    _fill_order_list(cfdata);
301    e_widget_table_object_append(ot, cfdata->o_list, 0, 0, 3, 1, 1, 1, 1, 1);
302    cfdata->o_up = e_widget_button_add(evas, _("Up"), "go-up",
303                                       _cb_up, cfdata, NULL);
304    e_widget_disabled_set(cfdata->o_up, EINA_TRUE);
305    e_widget_table_object_append(ot, cfdata->o_up, 0, 1, 1, 1, 1, 1, 1, 0);
306    cfdata->o_down = e_widget_button_add(evas, _("Down"), "go-down",
307                                         _cb_down, cfdata, NULL);
308    e_widget_disabled_set(cfdata->o_down, EINA_TRUE);
309    e_widget_table_object_append(ot, cfdata->o_down, 1, 1, 1, 1, 1, 1, 1, 0);
310    cfdata->o_del = e_widget_button_add(evas, _("Remove"), "list-remove",
311                                        _cb_order_del, cfdata, NULL);
312    e_widget_disabled_set(cfdata->o_del, EINA_TRUE);
313    e_widget_table_object_append(ot, cfdata->o_del, 2, 1, 1, 1, 1, 1, 1, 0);
314    e_widget_toolbook_page_append(otb, NULL, _("Order"), ot,
315                                  1, 1, 1, 1, 0.5, 0.0);
316
317    e_widget_toolbook_page_show(otb, 0);
318
319    if (cfdata->fill_delay) ecore_timer_del(cfdata->fill_delay);
320    cfdata->fill_delay = ecore_timer_add(0.2, _cb_fill_delay, cfdata);
321
322    e_dialog_resizable_set(cfd->dia, 1);
323    e_win_centered_set(cfd->dia->win, 1);
324    return otb;
325 }
326
327 static int
328 _basic_apply(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
329 {
330    const char *ext;
331
332    if ((!cfdata->data) || (!cfdata->data->filename)) return 0;
333    if (!(ext = strrchr(cfdata->data->filename, '.'))) return 0;
334    if (!strcmp(ext, ".menu"))
335      return _save_menu(cfdata);
336    else if (!strcmp(ext, ".order"))
337      return _save_order(cfdata);
338    return 1;
339 }
340
341 static Eina_List *
342 _load_menu(const char *path)
343 {
344    Efreet_Menu *menu, *entry;
345    Eina_List *apps = NULL, *l;
346
347    menu = efreet_menu_parse(path);
348    if ((!menu) || (!menu->entries))
349      {
350         if (menu) efreet_menu_free(menu);
351         return NULL;
352      }
353    EINA_LIST_FOREACH(menu->entries, l, entry)
354      {
355         if (entry->type != EFREET_MENU_ENTRY_DESKTOP) continue;
356         efreet_desktop_ref(entry->desktop);
357         apps = eina_list_append(apps, entry->desktop);
358      }
359    efreet_menu_free(menu);
360    return apps;
361 }
362
363 static Eina_List *
364 _load_order(const char *path)
365 {
366    E_Order *order = NULL;
367    Eina_List *apps = NULL, *l;
368    Efreet_Desktop *desk;
369
370    if (!path) return NULL;
371    if (!(order = e_order_new(path))) return NULL;
372    EINA_LIST_FOREACH(order->desktops, l, desk)
373      {
374         efreet_desktop_ref(desk);
375         apps = eina_list_append(apps, desk);
376      }
377    e_object_del(E_OBJECT(order));
378    return apps;
379 }
380
381 static int
382 _save_menu(E_Config_Dialog_Data *cfdata)
383 {
384    Eina_List *l;
385    Efreet_Menu *menu = NULL;
386    Efreet_Desktop *desk;
387    int ret;
388
389    menu = efreet_menu_new("Favorites");
390    EINA_LIST_FOREACH(cfdata->apps, l, desk)
391      {
392         if (!desk) continue;
393         efreet_menu_desktop_insert(menu, desk, -1);
394      }
395    ret = efreet_menu_save(menu, cfdata->data->filename);
396    efreet_menu_free(menu);
397    return ret;
398 }
399
400 static int
401 _save_order(E_Config_Dialog_Data *cfdata)
402 {
403    Eina_List *l;
404    E_Order *order = NULL;
405    Efreet_Desktop *desk;
406
407    if (!(order = e_order_new(cfdata->data->filename))) return 0;
408    e_order_clear(order);
409    EINA_LIST_FOREACH(cfdata->apps, l, desk)
410      {
411         if (!desk) continue;
412         e_order_append(order, desk);
413      }
414    e_object_del(E_OBJECT(order));
415    return 1;
416 }
417
418 static void
419 _list_items_state_set(E_Config_App_List *apps)
420 {
421    Evas *evas;
422    Eina_List *l;
423    Efreet_Desktop *desk;
424
425    if (!apps->o_list)
426      return;
427
428    evas = evas_object_evas_get(apps->o_list);
429    evas_event_freeze(evas);
430    edje_freeze();
431    e_widget_ilist_freeze(apps->o_list);
432    e_widget_ilist_clear(apps->o_list);
433
434    EINA_LIST_FOREACH(apps->desks, l, desk)
435      {
436         Evas_Object *icon = NULL, *end = NULL;
437
438         end = edje_object_add(evas);
439         if (!e_theme_edje_object_set(end, "base/theme/widgets",
440                                      "e/widgets/ilist/toggle_end"))
441           {
442              evas_object_del(end);
443              end = NULL;
444           }
445
446         if (!end) break;
447
448         if (eina_list_search_unsorted(apps->cfdata->apps, _cb_desks_sort, desk))
449           {
450              edje_object_signal_emit(end, "e,state,checked", "e");
451           }
452         else
453           {
454              edje_object_signal_emit(end, "e,state,unchecked", "e");
455           }
456
457         icon = e_util_desktop_icon_add(desk, 24, evas);
458         e_widget_ilist_append_full(apps->o_list, icon, end, desk->name,
459                                    _cb_apps_list_selected, apps, NULL);
460      }
461
462    e_widget_ilist_go(apps->o_list);
463    e_widget_ilist_thaw(apps->o_list);
464    edje_thaw();
465    evas_event_thaw(evas);
466 }
467
468 static void
469 _fill_apps_list(E_Config_App_List *apps)
470 {
471    Eina_List *desks = NULL;
472    Efreet_Desktop *desk = NULL;
473
474    desks = efreet_util_desktop_name_glob_list("*");
475    EINA_LIST_FREE(desks, desk)
476      {
477         Eina_List *ll;
478
479         if (desk->no_display)
480           {
481              efreet_desktop_free(desk);
482              continue;
483           }
484         ll = eina_list_search_unsorted_list(apps->desks, _cb_desks_sort, desk);
485         if (ll)
486           {
487              Efreet_Desktop *old;
488
489              old = eina_list_data_get(ll);
490              /*
491               * This fixes when we have several .desktop with the same name,
492               * and the only difference is that some of them are for specific
493               * desktops.
494               */
495              if ((old->only_show_in) && (!desk->only_show_in))
496                {
497                   efreet_desktop_free(old);
498                   eina_list_data_set(ll, desk);
499                }
500              else
501                efreet_desktop_free(desk);
502           }
503         else
504           apps->desks = eina_list_append(apps->desks, desk);
505      }
506    apps->desks = eina_list_sort(apps->desks, -1, _cb_desks_sort);
507
508    _list_items_state_set(apps);
509 }
510
511 static void
512 _fill_xdg_list(E_Config_App_List *apps)
513 {
514    Eina_List *files;
515    Efreet_Desktop *desk = NULL;
516    const char *path = "/etc/xdg/autostart";
517    char *file, *ext;
518    char buf[4096];
519
520    files = ecore_file_ls(path);
521    EINA_LIST_FREE(files, file)
522      {
523         Eina_List *ll;
524
525         if ((file[0] == '.') || !(ext = strrchr(file, '.')) || (strcmp(ext, ".desktop")))
526           {
527              free(file);
528              continue;
529           }
530         snprintf(buf, sizeof(buf), "%s/%s", path, file);
531         free(file);
532
533         desk = efreet_desktop_new(buf);
534         if (!desk)
535           continue;
536
537         ll = eina_list_search_unsorted_list(apps->desks, _cb_desks_sort, desk);
538         if (ll)
539           {
540              Efreet_Desktop *old;
541
542              old = eina_list_data_get(ll);
543              /*
544               * This fixes when we have several .desktop with the same name,
545               * and the only difference is that some of them are for specific
546               * desktops.
547               */
548              if ((old->only_show_in) && (!desk->only_show_in))
549                {
550                   efreet_desktop_free(old);
551                   eina_list_data_set(ll, desk);
552                }
553              else
554                efreet_desktop_free(desk);
555           }
556         else
557           apps->desks = eina_list_append(apps->desks, desk);
558      }
559
560    apps->desks = eina_list_sort(apps->desks, -1, _cb_desks_sort);
561
562    _list_items_state_set(apps);
563 }
564
565 static void
566 _fill_order_list(E_Config_Dialog_Data *cfdata)
567 {
568    Eina_List *l = NULL;
569    Efreet_Desktop *desk = NULL;
570    Evas *evas;
571
572    evas = evas_object_evas_get(cfdata->o_list);
573    evas_event_freeze(evas);
574    edje_freeze();
575    e_widget_ilist_freeze(cfdata->o_list);
576    e_widget_ilist_clear(cfdata->o_list);
577
578    EINA_LIST_FOREACH(cfdata->apps, l, desk)
579      {
580         Evas_Object *icon = NULL;
581
582         icon = e_util_desktop_icon_add(desk, 24, evas);
583         e_widget_ilist_append(cfdata->o_list, icon, desk->name,
584                               _cb_order_list_selected, cfdata, NULL);
585      }
586
587    e_widget_ilist_go(cfdata->o_list);
588    e_widget_ilist_thaw(cfdata->o_list);
589    edje_thaw();
590    evas_event_thaw(evas);
591 }
592
593 static void
594 _cb_apps_list_selected(void *data)
595 {
596    E_Config_App_List *apps;
597    const E_Ilist_Item *it;
598    const Eina_List *l;
599    unsigned int enabled = 0, disabled = 0;
600
601    if (!(apps = data)) return;
602    EINA_LIST_FOREACH(e_widget_ilist_items_get(apps->o_list), l, it)
603      {
604         if ((!it->selected) || (it->header)) continue;
605         if (eina_list_search_unsorted(apps->cfdata->apps, _cb_desks_name, it->label))
606           enabled++;
607         else
608           disabled++;
609      }
610
611    if (apps->o_desc)
612      {
613         Efreet_Desktop *desk;
614         int sel;
615
616         sel = e_widget_ilist_selected_get(apps->o_list);
617         desk = eina_list_nth(apps->desks, sel);
618         if (desk)
619           e_widget_textblock_markup_set(apps->o_desc, desk->comment);
620      }
621
622    e_widget_disabled_set(apps->o_add, !disabled);
623    e_widget_disabled_set(apps->o_del, !enabled);
624 }
625
626 static void
627 _cb_order_list_selected(void *data)
628 {
629    E_Config_Dialog_Data *cfdata;
630    int sel, count;
631
632    if (!(cfdata = data)) return;
633    sel = e_widget_ilist_selected_get(cfdata->o_list);
634    count = eina_list_count(cfdata->apps);
635    e_widget_disabled_set(cfdata->o_up, (sel == 0));
636    e_widget_disabled_set(cfdata->o_down, !(sel < (count - 1)));
637    e_widget_disabled_set(cfdata->o_del, EINA_FALSE);
638 }
639
640 static int
641 _cb_desks_name(const void *data1, const void *data2)
642 {
643    const Efreet_Desktop *d1;
644    const char *d2;
645
646    if (!(d1 = data1)) return 1;
647    if (!d1->name) return 1;
648    if (!(d2 = data2)) return -1;
649    return strcmp(d1->name, d2);
650 }
651
652 static int
653 _cb_desks_sort(const void *data1, const void *data2)
654 {
655    const Efreet_Desktop *d1, *d2;
656
657    if (!(d1 = data1)) return 1;
658    if (!d1->name) return 1;
659    if (!(d2 = data2)) return -1;
660    if (!d2->name) return -1;
661    return strcmp(d1->name, d2->name);
662 }
663
664 static void
665 _cb_add(void *data, void *data2 __UNUSED__)
666 {
667    E_Config_App_List *apps;
668    const E_Ilist_Item *it;
669    const Eina_List *l;
670
671    if (!(apps = data)) return;
672    EINA_LIST_FOREACH(e_widget_ilist_items_get(apps->o_list), l, it)
673      {
674         Efreet_Desktop *desk;
675
676         if ((!it->selected) || (it->header)) continue;
677         if (!(desk = eina_list_search_unsorted(apps->desks, _cb_desks_name, it->label))) continue;
678         if (!eina_list_search_unsorted(apps->cfdata->apps, _cb_desks_sort, desk))
679           {
680              Evas_Object *end;
681
682              end = e_widget_ilist_item_end_get(it);
683              if (end) edje_object_signal_emit(end, "e,state,checked", "e");
684              efreet_desktop_ref(desk);
685              apps->cfdata->apps = eina_list_append(apps->cfdata->apps, desk);
686           }
687      }
688    e_widget_ilist_unselect(apps->o_list);
689    e_widget_disabled_set(apps->o_add, EINA_TRUE);
690    e_widget_disabled_set(apps->o_del, EINA_TRUE);
691    _fill_order_list(apps->cfdata);
692 }
693
694 static void
695 _cb_del(void *data, void *data2 __UNUSED__)
696 {
697    E_Config_App_List *apps;
698    const E_Ilist_Item *it;
699    const Eina_List *l;
700
701    if (!(apps = data)) return;
702    EINA_LIST_FOREACH(e_widget_ilist_items_get(apps->o_list), l, it)
703      {
704         Efreet_Desktop *desk;
705
706         if ((!it->selected) || (it->header)) continue;
707         if ((desk = eina_list_search_unsorted(apps->cfdata->apps, _cb_desks_name, it->label)))
708           {
709              Evas_Object *end;
710
711              end = e_widget_ilist_item_end_get(it);
712              if (end) edje_object_signal_emit(end, "e,state,unchecked", "e");
713              apps->cfdata->apps = eina_list_remove(apps->cfdata->apps, desk);
714              efreet_desktop_unref(desk);
715           }
716      }
717
718    e_widget_ilist_unselect(apps->o_list);
719    e_widget_disabled_set(apps->o_add, EINA_TRUE);
720    e_widget_disabled_set(apps->o_del, EINA_TRUE);
721    _fill_order_list(apps->cfdata);
722 }
723
724 static void
725 _cb_order_del(void *data, void *data2 __UNUSED__)
726 {
727    E_Config_Dialog_Data *cfdata;
728    const E_Ilist_Item *it;
729    const Eina_List *l;
730
731    if (!(cfdata = data)) return;
732    EINA_LIST_FOREACH(e_widget_ilist_items_get(cfdata->o_list), l, it)
733      {
734         Efreet_Desktop *desk;
735
736         if ((!it->selected) || (it->header)) continue;
737
738         if ((desk = eina_list_search_unsorted(cfdata->apps, _cb_desks_name, it->label)))
739           {
740              cfdata->apps = eina_list_remove(cfdata->apps, desk);
741              efreet_desktop_unref(desk);
742           }
743      }
744
745    _list_items_state_set(&(cfdata->apps_xdg));
746    _list_items_state_set(&(cfdata->apps_user));
747
748    e_widget_ilist_unselect(cfdata->o_list);
749    e_widget_disabled_set(cfdata->o_del, EINA_TRUE);
750    _fill_order_list(cfdata);
751 }
752
753 static void
754 _cb_up(void *data, void *data2 __UNUSED__)
755 {
756    E_Config_Dialog_Data *cfdata;
757    Eina_List *l;
758    Evas *evas;
759    const char *lbl;
760    int sel;
761
762    if (!(cfdata = data)) return;
763    evas = evas_object_evas_get(cfdata->o_list);
764    evas_event_freeze(evas);
765    edje_freeze();
766    e_widget_ilist_freeze(cfdata->o_list);
767
768    sel = e_widget_ilist_selected_get(cfdata->o_list);
769    lbl = e_widget_ilist_selected_label_get(cfdata->o_list);
770    if ((l = eina_list_search_unsorted_list(cfdata->apps, _cb_desks_name, lbl)))
771      {
772         Efreet_Desktop *desk;
773         Evas_Object *icon = NULL;
774
775         desk = eina_list_data_get(l);
776         if (l->prev)
777           {
778              Eina_List *ll;
779
780              ll = l->prev;
781              cfdata->apps = eina_list_remove_list(cfdata->apps, l);
782              cfdata->apps = eina_list_prepend_relative_list(cfdata->apps, desk, ll);
783
784              e_widget_ilist_remove_num(cfdata->o_list, sel);
785              e_widget_ilist_go(cfdata->o_list);
786              icon = e_util_desktop_icon_add(desk, 24, evas);
787              e_widget_ilist_prepend_relative(cfdata->o_list, icon, desk->name,
788                                              _cb_order_list_selected, cfdata,
789                                              NULL, (sel - 1));
790              e_widget_ilist_selected_set(cfdata->o_list, (sel - 1));
791           }
792      }
793
794    e_widget_ilist_go(cfdata->o_list);
795    e_widget_ilist_thaw(cfdata->o_list);
796    edje_thaw();
797    evas_event_thaw(evas);
798 }
799
800 static void
801 _cb_down(void *data, void *data2 __UNUSED__)
802 {
803    E_Config_Dialog_Data *cfdata;
804    Eina_List *l;
805    Evas *evas;
806    const char *lbl;
807    int sel;
808
809    if (!(cfdata = data)) return;
810    evas = evas_object_evas_get(cfdata->o_list);
811    evas_event_freeze(evas);
812    edje_freeze();
813    e_widget_ilist_freeze(cfdata->o_list);
814
815    sel = e_widget_ilist_selected_get(cfdata->o_list);
816    lbl = e_widget_ilist_selected_label_get(cfdata->o_list);
817    if ((l = eina_list_search_unsorted_list(cfdata->apps, _cb_desks_name, lbl)))
818      {
819         Efreet_Desktop *desk;
820         Evas_Object *icon = NULL;
821
822         desk = eina_list_data_get(l);
823         if (l->next)
824           {
825              Eina_List *ll;
826
827              ll = l->next;
828              cfdata->apps = eina_list_remove_list(cfdata->apps, l);
829              cfdata->apps = eina_list_append_relative_list(cfdata->apps, desk, ll);
830
831              e_widget_ilist_remove_num(cfdata->o_list, sel);
832              e_widget_ilist_go(cfdata->o_list);
833              icon = e_util_desktop_icon_add(desk, 24, evas);
834              e_widget_ilist_append_relative(cfdata->o_list, icon, desk->name,
835                                             _cb_order_list_selected, cfdata,
836                                             NULL, sel);
837              e_widget_ilist_selected_set(cfdata->o_list, (sel + 1));
838           }
839      }
840
841    e_widget_ilist_go(cfdata->o_list);
842    e_widget_ilist_thaw(cfdata->o_list);
843    edje_thaw();
844    evas_event_thaw(evas);
845 }
846
847 static Eina_Bool
848 _cb_fill_delay(void *data)
849 {
850    E_Config_Dialog_Data *cfdata;
851    int mw;
852
853    if (!(cfdata = data)) return ECORE_CALLBACK_CANCEL;
854    _fill_apps_list(&cfdata->apps_user);
855    e_widget_size_min_get(cfdata->apps_user.o_list, &mw, NULL);
856    if (mw < (200 * e_scale)) mw = (200 * e_scale);
857    e_widget_size_min_set(cfdata->apps_user.o_list, mw, (175 * e_scale));
858
859    if (cfdata->data->show_autostart)
860      {
861         _fill_xdg_list(&cfdata->apps_xdg);
862         e_widget_size_min_get(cfdata->apps_xdg.o_list, &mw, NULL);
863         if (mw < (200 * e_scale)) mw = (200 * e_scale);
864         e_widget_size_min_set(cfdata->apps_xdg.o_list, mw, (175 * e_scale));
865      }
866
867    cfdata->fill_delay = NULL;
868    return ECORE_CALLBACK_CANCEL;
869 }
870