Tizen 2.1 release
[platform/core/uifw/e17.git] / src / modules / quickaccess / e_mod_config.c
1 #include "e_mod_main.h"
2
3 typedef struct Config_Entry
4 {
5    EINA_INLIST;
6    const char *id;
7    E_Quick_Access_Entry *entry;
8 } Config_Entry;
9
10 struct _E_Config_Dialog_Data
11 {
12    const char *entry;
13    Evas_Object *o_list_entry;
14    Evas_Object *o_list_transient;
15    E_Entry_Dialog *ed;
16
17    Eina_Inlist *entries;
18    Eina_Inlist *transient_entries;
19
20    int autohide;
21    int hide_when_behind;
22    int skip_taskbar;
23    int skip_pager;
24
25    int dont_bug_me;
26    int first_run;
27 };
28
29 static E_Config_DD *conf_edd, *entry_edd;
30
31 /**
32  * in priority order:
33  *
34  * @todo configure match name (to be used by actions)
35  *
36  * @todo configure match icccm match class and name.
37  *
38  * @todo configure show/hide effects:
39  *        - fullscreen
40  *        - centered
41  *        - slide from top, bottom, left or right
42  *
43  * @todo match more than one, doing tabs (my idea is to do another
44  *       tabbing module first, experiment with that, maybe use/reuse
45  *       it here)
46  */
47
48 static Config_Entry *
49 _config_entry_new(E_Quick_Access_Entry *entry)
50 {
51    Config_Entry *ce;
52
53    ce = E_NEW(Config_Entry, 1);
54    ce->entry = entry;
55    entry->cfg_entry = ce;
56    return ce;
57 }
58
59 static void
60 _config_entry_free(Config_Entry *ce)
61 {
62    if (!ce) return;
63    ce->entry->cfg_entry = NULL;
64    eina_stringshare_del(ce->id);
65    if (ce->entry->transient)
66      qa_mod->cfd->cfdata->transient_entries = eina_inlist_remove(qa_mod->cfd->cfdata->transient_entries, EINA_INLIST_GET(ce));
67    else
68      qa_mod->cfd->cfdata->entries = eina_inlist_remove(qa_mod->cfd->cfdata->entries, EINA_INLIST_GET(ce));
69    free(ce);
70 }
71
72 static void
73 _fill_data(E_Config_Dialog_Data *cfdata)
74 {
75    Eina_List *l;
76    E_Quick_Access_Entry *entry;
77
78    cfdata->autohide = qa_config->autohide;
79    cfdata->hide_when_behind = qa_config->hide_when_behind;
80    cfdata->skip_taskbar = qa_config->skip_taskbar;
81    cfdata->skip_pager = qa_config->skip_pager;
82
83    cfdata->dont_bug_me = qa_config->dont_bug_me;
84    cfdata->first_run = qa_config->first_run;
85
86    EINA_LIST_FOREACH(qa_config->entries, l, entry)
87      cfdata->entries = eina_inlist_append(cfdata->entries, EINA_INLIST_GET(_config_entry_new(entry)));
88
89    EINA_LIST_FOREACH(qa_config->transient_entries, l, entry)
90      cfdata->transient_entries = eina_inlist_append(cfdata->transient_entries, EINA_INLIST_GET(_config_entry_new(entry)));
91 }
92
93 static void *
94 _create_data(E_Config_Dialog *cfd)
95 {
96    E_Config_Dialog_Data *cfdata;
97
98    cfdata = E_NEW(E_Config_Dialog_Data, 1);
99    _fill_data(cfdata);
100    qa_mod->cfd = cfd;
101    return cfdata;
102 }
103
104 static void
105 _free_data(E_Config_Dialog *cfd  __UNUSED__, E_Config_Dialog_Data *cfdata)
106 {
107    Eina_Inlist *l;
108    Config_Entry *ce;
109    EINA_INLIST_FOREACH_SAFE(cfdata->entries, l, ce)
110      _config_entry_free(ce);
111    EINA_INLIST_FOREACH_SAFE(cfdata->transient_entries, l, ce)
112      _config_entry_free(ce);
113    free(cfdata);
114    qa_mod->cfd = NULL;
115 }
116
117 static int
118 _advanced_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
119 {
120    Config_Entry *ce;
121 #define CHECK(X) \
122    if (cfdata->X != qa_config->X) return 1
123
124    CHECK(dont_bug_me);
125    CHECK(first_run);
126
127    EINA_INLIST_FOREACH(cfdata->entries, ce)
128      if (ce->id) return 1;
129    EINA_INLIST_FOREACH(cfdata->transient_entries, ce)
130      if (ce->id) return 1;
131
132 #undef CHECK
133    return 0;
134 }
135
136 static int
137 _basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
138 {
139 #define CHECK(X) \
140    if (cfdata->X != qa_config->X) return 1
141
142    CHECK(autohide);
143    CHECK(skip_pager);
144    CHECK(skip_taskbar);
145    CHECK(hide_when_behind);
146
147 #undef CHECK
148    return 0;
149 }
150
151 static void
152 _list_select(void *data)
153 {
154    (void) data;
155 }
156
157 static void
158 _list_fill(E_Config_Dialog_Data *cfdata, Evas_Object *list, Eina_Bool transient)
159 {
160    Config_Entry *ce;
161    EINA_INLIST_FOREACH(transient ? cfdata->transient_entries : cfdata->entries, ce)
162      {
163         e_widget_ilist_append(list, NULL, ce->id ?: ce->entry->id, _list_select, ce, ce->entry->id);
164      }
165    e_widget_ilist_selected_set(list, 0);
166 }
167
168 static void
169 _rename_del(void *data)
170 {
171    E_Config_Dialog_Data *cfdata = e_object_data_get(data);
172    if (!cfdata) return;
173    cfdata->ed = NULL;
174 }
175
176 static void
177 _rename_ok(void *data, char *text)
178 {
179    Config_Entry *ce = data;
180    const char *name;
181    Evas_Object *list;
182
183    name = eina_stringshare_add(text);
184    if (name == ce->id)
185      {
186         eina_stringshare_del(name);
187         return;
188      }
189    if (name == ce->entry->id)
190      {
191         eina_stringshare_del(name);
192         if (!ce->id) return;
193         eina_stringshare_replace(&ce->id, NULL);
194      }
195    else
196      eina_stringshare_replace(&ce->id, text);
197    list = ce->entry->transient ? qa_mod->cfd->cfdata->o_list_transient : qa_mod->cfd->cfdata->o_list_entry;
198    e_widget_ilist_clear(list);
199    _list_fill(qa_mod->cfd->cfdata, list, ce->entry->transient);
200 }
201
202 static void
203 _list_delete(void *data __UNUSED__, void *list)
204 {
205    Config_Entry *ce;
206
207    ce = e_widget_ilist_selected_data_get(list);
208    if (!ce) return;
209    e_qa_entry_free(ce->entry);
210 }
211
212 static void
213 _list_rename(void *data, void *list)
214 {
215    E_Config_Dialog_Data *cfdata = data;
216    Config_Entry *ce;
217
218    if (cfdata->ed)
219      {
220         e_win_raise(cfdata->ed->dia->win);
221         return;
222      }
223
224    ce = e_widget_ilist_selected_data_get(list);
225    if (!ce) return;
226    cfdata->ed = e_entry_dialog_show(_("Rename"), "edit-rename", _("Enter a unique name for this entry"),
227                                     ce->id ?: ce->entry->id, NULL, NULL,
228                                     _rename_ok, NULL, ce);
229    e_object_data_set(E_OBJECT(cfdata->ed), cfdata);
230    e_object_del_attach_func_set(E_OBJECT(cfdata->ed), _rename_del);
231 }
232
233 static Evas_Object *
234 _advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
235 {
236    Evas_Object *ob, *ol, *otb, *tab;
237    int w, h;
238
239    tab = e_widget_table_add(evas, 0);
240    evas_object_name_set(tab, "dia_table");
241
242    otb = e_widget_toolbook_add(evas, 48 * e_scale, 48 * e_scale);
243
244 /////////////////////////////////////////////////////////////////
245    ol = e_widget_list_add(evas, 0, 0);
246    ob = e_widget_check_add(evas, _("Disable Warning Dialogs"), (int*)&(cfdata->dont_bug_me));
247    e_widget_list_object_append(ol, ob, 1, 0, 0.5);
248    ob = e_widget_check_add(evas, _("Disable Startup Tutorial"), (int*)&(cfdata->first_run));
249    e_widget_list_object_append(ol, ob, 1, 0, 0.5);
250
251    e_widget_toolbook_page_append(otb, NULL, _("Behavior"), ol, 1, 1, 1, 1, 0.5, 0.5);
252
253 /////////////////////////////////////////////////////////////////
254    ol = e_widget_table_add(evas, 0);
255    e_widget_table_freeze(ol);
256
257    cfdata->o_list_entry = ob = e_widget_ilist_add(evas, 0, 0, &cfdata->entry);
258    evas_event_freeze(evas_object_evas_get(ob));
259    edje_freeze();
260    e_widget_ilist_freeze(ob);
261
262    _list_fill(cfdata, ob, EINA_FALSE);
263
264    e_widget_size_min_get(ob, &w, &h);
265    e_widget_size_min_set(ob, MIN(w, 200), MIN(h, 100));
266    e_widget_ilist_go(ob);
267    e_widget_ilist_thaw(ob);
268    edje_thaw();
269    evas_event_thaw(evas_object_evas_get(ol));
270
271    e_widget_table_object_append(ol, ob, 0, 0, 2, 1, 1, 1, 1, 1);
272
273    ob = e_widget_button_add(evas, _("Rename"), "edit-rename", _list_rename, cfdata, cfdata->o_list_entry);
274    e_widget_table_object_append(ol, ob, 0, 1, 1, 1, 1, 1, 0, 0);
275
276    ob = e_widget_button_add(evas, _("Delete"), "edit-delete", _list_delete, cfdata, cfdata->o_list_entry);
277    e_widget_table_object_append(ol, ob, 1, 1, 1, 1, 1, 1, 0, 0);
278
279
280    e_widget_table_thaw(ol);
281
282    e_widget_toolbook_page_append(otb, NULL, _("Entries"), ol, 1, 1, 1, 1, 0.5, 0.5);
283 /////////////////////////////////////////////////////////////////
284    ol = e_widget_table_add(evas, 0);
285    e_widget_table_freeze(ol);
286
287    cfdata->o_list_transient = ob = e_widget_ilist_add(evas, 0, 0, &cfdata->entry);
288    evas_event_freeze(evas_object_evas_get(ob));
289    edje_freeze();
290    e_widget_ilist_freeze(ob);
291
292    _list_fill(cfdata, ob, EINA_TRUE);
293
294    e_widget_size_min_get(ob, &w, &h);
295    e_widget_size_min_set(ob, MIN(w, 200), MIN(h, 100));
296    e_widget_ilist_go(ob);
297    e_widget_ilist_thaw(ob);
298    edje_thaw();
299    evas_event_thaw(evas_object_evas_get(ol));
300
301    e_widget_table_object_append(ol, ob, 0, 0, 2, 1, 1, 1, 1, 1);
302
303    ob = e_widget_button_add(evas, _("Rename"), "edit-rename", _list_rename, cfdata, cfdata->o_list_transient);
304    e_widget_table_object_append(ol, ob, 0, 1, 1, 1, 1, 1, 0, 0);
305
306    ob = e_widget_button_add(evas, _("Delete"), "edit-delete", _list_delete, cfdata, cfdata->o_list_transient);
307    e_widget_table_object_append(ol, ob, 1, 1, 1, 1, 1, 1, 0, 0);
308
309    e_widget_table_thaw(ol);
310
311    e_widget_toolbook_page_append(otb, NULL, _("Transients"), ol, 1, 1, 1, 1, 0.5, 0.5);
312 /////////////////////////////////////////////////////////////////
313    e_widget_toolbook_page_show(otb, 0);
314
315    e_dialog_resizable_set(cfd->dia, 1);
316
317    e_widget_table_object_append(tab, otb, 0, 0, 1, 1, 1, 1, 1, 1);
318    return tab;
319 }
320
321 static Evas_Object *
322 _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
323 {
324    Evas_Object *ob, *ol, *otb, *tab;
325
326    cfdata->o_list_entry = cfdata->o_list_transient = NULL;
327
328    tab = e_widget_table_add(evas, 0);
329    evas_object_name_set(tab, "dia_table");
330
331    otb = e_widget_toolbook_add(evas, 48 * e_scale, 48 * e_scale);
332
333    ol = e_widget_list_add(evas, 0, 0);
334
335    ob = e_widget_check_add(evas, _("Hide Instead Of Raising"), &cfdata->hide_when_behind);
336    e_widget_list_object_append(ol, ob, 1, 0, 0.5);
337
338    ob = e_widget_check_add(evas, _("Hide If Focus Lost"), &cfdata->autohide);
339    e_widget_list_object_append(ol, ob, 1, 0, 0.5);
340
341    ob = e_widget_check_add(evas, _("Skip Taskbar"), &cfdata->skip_taskbar);
342    e_widget_list_object_append(ol, ob, 1, 0, 0.5);
343
344    ob = e_widget_check_add(evas, _("Skip Pager"), &cfdata->skip_pager);
345    e_widget_list_object_append(ol, ob, 1, 0, 0.5);
346
347    e_widget_toolbook_page_append(otb, NULL, _("Behavior"), ol, 1, 1, 1, 1, 0.5, 0.5);
348
349    e_widget_toolbook_page_show(otb, 0);
350
351    e_dialog_resizable_set(cfd->dia, 1);
352
353    e_widget_table_object_append(tab, otb, 0, 0, 1, 1, 1, 1, 1, 1);
354    return tab;
355 }
356
357
358 static int
359 _advanced_apply_data(E_Config_Dialog *cfd  __UNUSED__, E_Config_Dialog_Data *cfdata)
360 {
361    Config_Entry *ce;
362    Eina_Bool entry_changed = EINA_FALSE, transient_changed = EINA_FALSE;
363 #define SET(X) qa_config->X = cfdata->X
364
365    SET(dont_bug_me);
366    SET(first_run);
367
368    EINA_INLIST_FOREACH(cfdata->entries, ce)
369      {
370         if (!ce->id) continue;
371         if (!e_qa_entry_rename(ce->entry, ce->id))
372           entry_changed = EINA_TRUE;
373         eina_stringshare_replace(&ce->id, NULL);
374      }
375    EINA_INLIST_FOREACH(cfdata->transient_entries, ce)
376      {
377         if (!ce->id) continue;
378         if (!e_qa_entry_rename(ce->entry, ce->id))
379           transient_changed = EINA_TRUE;
380         eina_stringshare_replace(&ce->id, NULL);
381      }
382    if (entry_changed)
383      {
384         e_widget_ilist_clear(cfdata->o_list_entry);
385         _list_fill(qa_mod->cfd->cfdata, cfdata->o_list_entry, EINA_FALSE);
386      }
387    if (transient_changed)
388      {
389         e_widget_ilist_clear(cfdata->o_list_transient);
390         _list_fill(qa_mod->cfd->cfdata, cfdata->o_list_transient, EINA_TRUE);
391      }
392    e_config_save_queue();
393    return 1;
394 }
395
396 static int
397 _basic_apply_data(E_Config_Dialog *cfd  __UNUSED__, E_Config_Dialog_Data *cfdata)
398 {
399 #define SET(X) qa_config->X = cfdata->X
400    SET(autohide);
401    SET(hide_when_behind);
402    SET(skip_taskbar);
403    SET(skip_pager);
404    e_qa_entries_update();
405    e_config_save_queue();
406    return 1;
407 }
408
409 static void
410 _list_item_add(E_Quick_Access_Entry *entry)
411 {
412    Evas_Object *list;
413    Config_Entry *ce = entry->cfg_entry;
414
415    list = ce->entry->transient ? qa_mod->cfd->cfdata->o_list_transient : qa_mod->cfd->cfdata->o_list_entry;
416    if (!list) return;
417    e_widget_ilist_append(list, NULL, ce->id ?: ce->entry->id, _list_select, ce, ce->entry->id);
418    if (e_widget_ilist_selected_get(list) == -1) e_widget_ilist_selected_set(list, 0);
419 }
420
421 static void
422 _list_item_delete(E_Quick_Access_Entry *entry)
423 {
424    const Eina_List *l, *ll;
425    E_Ilist_Item *ili;
426    Evas_Object *list;
427    unsigned int x = 0;
428
429    list = entry->transient ? qa_mod->cfd->cfdata->o_list_transient : qa_mod->cfd->cfdata->o_list_entry;
430    if (!list) return;
431    l = e_widget_ilist_items_get(list);
432    EINA_LIST_FOREACH(l, ll, ili)
433      {
434         if (e_widget_ilist_item_data_get(ili) == entry->cfg_entry)
435           {
436              e_widget_ilist_remove_num(list, x);
437              break;
438           }
439         x++;
440      }
441    if (e_widget_ilist_selected_get(list) == -1) e_widget_ilist_selected_set(list, 0);
442 }
443 //////////////////////////////////////////////////////////////////////////////
444 E_Config_DD *
445 e_qa_config_dd_new(void)
446 {
447    conf_edd = E_CONFIG_DD_NEW("Quickaccess_Config", Config);
448    entry_edd = E_CONFIG_DD_NEW("E_Quick_Access_Entry", E_Quick_Access_Entry);
449
450 #undef T
451 #undef D
452 #define T E_Quick_Access_Entry
453 #define D entry_edd
454    E_CONFIG_VAL(D, T, id, STR);
455    E_CONFIG_VAL(D, T, name, STR);
456    E_CONFIG_VAL(D, T, class, STR);
457    E_CONFIG_VAL(D, T, cmd, STR);
458    E_CONFIG_VAL(D, T, win, UINT);
459    E_CONFIG_VAL(D, T, config.autohide, UCHAR);
460    E_CONFIG_VAL(D, T, config.relaunch, UCHAR);
461    E_CONFIG_VAL(D, T, config.hidden, UCHAR);
462    E_CONFIG_VAL(D, T, config.jump, UCHAR);
463    E_CONFIG_VAL(D, T, transient, UCHAR);
464 #undef T
465 #undef D
466 #define T Config
467 #define D conf_edd
468    E_CONFIG_VAL(D, T, config_version, UINT);
469    E_CONFIG_LIST(D, T, entries, entry_edd);
470    E_CONFIG_LIST(D, T, transient_entries, entry_edd);
471    E_CONFIG_VAL(D, T, autohide, UCHAR);
472    E_CONFIG_VAL(D, T, hide_when_behind, UCHAR);
473    E_CONFIG_VAL(D, T, skip_taskbar, UCHAR);
474    E_CONFIG_VAL(D, T, skip_pager, UCHAR);
475    E_CONFIG_VAL(D, T, dont_bug_me, UCHAR);
476    E_CONFIG_VAL(D, T, first_run, UCHAR);
477    return conf_edd;
478 }
479
480 void *
481 e_qa_config_dd_free(void)
482 {
483    E_CONFIG_DD_FREE(entry_edd);
484    E_CONFIG_DD_FREE(conf_edd);
485    return NULL;
486 }
487
488 void
489 e_qa_config_free(Config *conf)
490 {
491    if (!conf) return;
492    E_FREE_LIST(conf->entries, e_qa_entry_free);
493    E_FREE_LIST(conf->transient_entries, e_qa_entry_free);
494    free(conf);
495 }
496
497 Config *
498 e_qa_config_new(void)
499 {
500    Config *conf;
501
502    conf = E_NEW(Config, 1);
503    conf->skip_taskbar = 1;
504    conf->skip_pager = 1;
505    return conf;
506 }
507
508 void
509 e_qa_config_entry_transient_convert(E_Quick_Access_Entry *entry)
510 {
511    if (!entry) return;
512    if (!entry->cfg_entry) return;
513    _list_item_delete(entry);
514    entry->transient = !entry->transient;
515    _list_item_add(entry);
516    entry->transient = !entry->transient;
517 }
518
519 void
520 e_qa_config_entry_free(E_Quick_Access_Entry *entry)
521 {
522    if (!entry) return;
523    if (!entry->cfg_entry) return;
524    _list_item_delete(entry);
525    _config_entry_free(entry->cfg_entry);
526    entry->cfg_entry = NULL;
527 }
528
529 void
530 e_qa_config_entry_add(E_Quick_Access_Entry *entry)
531 {
532    Config_Entry *ce;
533
534    if (!entry) return;
535    if (!qa_mod->cfd) return;
536    ce = _config_entry_new(entry);
537    if (entry->transient)
538      qa_mod->cfd->cfdata->transient_entries = eina_inlist_append(qa_mod->cfd->cfdata->transient_entries, EINA_INLIST_GET(ce));
539    else
540      qa_mod->cfd->cfdata->entries = eina_inlist_append(qa_mod->cfd->cfdata->entries, EINA_INLIST_GET(ce));
541    _list_item_add(entry);
542 }
543
544 E_Config_Dialog *
545 e_int_config_qa_module(E_Container *con, const char *params __UNUSED__)
546 {
547    E_Config_Dialog *cfd;
548    E_Config_Dialog_View *v;
549    char buf[PATH_MAX];
550
551    if (qa_mod->cfd) return NULL;
552    v = E_NEW(E_Config_Dialog_View, 1);
553
554    v->create_cfdata = _create_data;
555    v->free_cfdata = _free_data;
556    v->basic.apply_cfdata = _basic_apply_data;
557    v->basic.create_widgets = _basic_create_widgets;
558    v->basic.check_changed = _basic_check_changed;
559    v->advanced.apply_cfdata = _advanced_apply_data;
560    v->advanced.create_widgets = _advanced_create_widgets;
561    v->advanced.check_changed = _advanced_check_changed;
562
563    snprintf(buf, sizeof(buf), "%s/e-module-quickaccess.edj", e_module_dir_get(qa_mod->module));
564    cfd = e_config_dialog_new(con, _("Quickaccess Settings"),
565                              "E", "launcher/quickaccess", buf, 32, v, NULL);
566    return cfd;
567 }