Tizen 2.1 release
[platform/core/uifw/e17.git] / src / bin / e_config_dialog.c
1 #include "e.h"
2
3 /* local subsystem functions */
4 static void      _e_config_dialog_free(E_Config_Dialog *cfd);
5 static void      _e_config_dialog_go(E_Config_Dialog *cfd, E_Config_Dialog_CFData_Type type);
6 static Eina_Bool _e_config_dialog_cb_auto_apply_timer(void *data);
7 static void      _e_config_dialog_cb_dialog_del(void *obj);
8 static void      _e_config_dialog_cb_ok(void *data, E_Dialog *dia);
9 static void      _e_config_dialog_cb_apply(void *data, E_Dialog *dia);
10 static void      _e_config_dialog_cb_advanced(void *data, void *data2);
11 static void      _e_config_dialog_cb_basic(void *data, void *data2);
12 static int       _e_config_dialog_check_changed(E_Config_Dialog *cfd, unsigned char def);
13 static void      _e_config_dialog_cb_changed(void *data, Evas_Object *obj);
14 static void      _e_config_dialog_cb_close(void *data, E_Dialog *dia);
15
16 /* local subsystem globals */
17 static Eina_List *_e_config_dialog_list = NULL;
18
19 /* externally accessible functions */
20
21 /**  
22  * Creates a new dialog  
23  *
24  * @param con the container the dialog will be added too
25  * @param title to display for the dialog
26  * @param name the name used to register the window in e
27  * @param class the call used to register the window in e
28  * @param icon the path to the icon file
29  * @param icon_size is of the width and height of the icon
30  * @param view the callbacks used to create the dialog and save the settings
31  * @param data additional data to attach to the dialog, will be passed to the callbacks
32  * @return returns the created dialog. Null on failure
33  */
34 EAPI E_Config_Dialog *
35 e_config_dialog_new(E_Container *con, const char *title, const char *name, const char *class, const char *icon, int icon_size, E_Config_Dialog_View *view, void *data)
36 {
37    E_Config_Dialog *cfd;
38
39    cfd = E_OBJECT_ALLOC(E_Config_Dialog, E_CONFIG_DIALOG_TYPE,
40                         _e_config_dialog_free);
41    cfd->view = view;
42    cfd->con = con;
43    cfd->title = eina_stringshare_add(title);
44    cfd->name = eina_stringshare_add(name);
45    cfd->class = eina_stringshare_add(class);
46    if (icon)
47      {
48         cfd->icon = eina_stringshare_add(icon);
49         cfd->icon_size = icon_size;
50      }
51    cfd->data = data;
52    cfd->hide_buttons = 1;
53    cfd->cfg_changed = 0;
54    cfd->cfg_changed_auto = 1;
55
56    if (cfd->view->override_auto_apply)
57      {
58         /* Dialog Requested To Not Auto-Apply */
59         if ((cfd->view->basic.apply_cfdata) ||
60             (cfd->view->advanced.apply_cfdata))
61           cfd->hide_buttons = 0;
62      }
63    else
64      {
65         /* Ok To Override, Or Not Specified. Use Config Value */
66         if (e_config->cfgdlg_auto_apply)
67           cfd->hide_buttons = 1;
68         else
69           {
70              if ((cfd->view->basic.apply_cfdata) ||
71                  (cfd->view->advanced.apply_cfdata))
72                cfd->hide_buttons = 0;
73           }
74      }
75
76    switch (e_config->cfgdlg_default_mode)
77      {
78       case E_CONFIG_DIALOG_CFDATA_TYPE_BASIC:
79         if (cfd->view->basic.create_widgets)
80           _e_config_dialog_go(cfd, E_CONFIG_DIALOG_CFDATA_TYPE_BASIC);
81         break;
82
83       case E_CONFIG_DIALOG_CFDATA_TYPE_ADVANCED:
84         if (cfd->view->advanced.create_widgets)
85           _e_config_dialog_go(cfd, E_CONFIG_DIALOG_CFDATA_TYPE_ADVANCED);
86         else if (cfd->view->basic.create_widgets)
87           _e_config_dialog_go(cfd, E_CONFIG_DIALOG_CFDATA_TYPE_BASIC);
88         break;
89      }
90    _e_config_dialog_list = eina_list_append(_e_config_dialog_list, cfd);
91
92    return cfd;
93 }
94
95 EAPI int
96 e_config_dialog_find(const char *name, const char *class)
97 {
98    Eina_List *l;
99    E_Config_Dialog *cfd;
100
101    EINA_LIST_FOREACH(_e_config_dialog_list, l, cfd)
102      {
103         if ((!e_util_strcmp(name, cfd->name)) &&
104             (!e_util_strcmp(class, cfd->class)))
105           {
106              E_Zone *z;
107
108              z = e_util_zone_current_get(e_manager_current_get());
109              e_border_uniconify(cfd->dia->win->border);
110              e_win_raise(cfd->dia->win);
111              if (z->container == cfd->dia->win->border->zone->container)
112                e_border_desk_set(cfd->dia->win->border, e_desk_current_get(z));
113              else
114                {
115                   if (!cfd->dia->win->border->sticky)
116                     e_desk_show(cfd->dia->win->border->desk);
117                   ecore_x_pointer_warp(cfd->dia->win->border->zone->container->win,
118                                        cfd->dia->win->border->zone->x + (cfd->dia->win->border->zone->w / 2),
119                                        cfd->dia->win->border->zone->y + (cfd->dia->win->border->zone->h / 2));
120                }
121              e_border_unshade(cfd->dia->win->border, E_DIRECTION_DOWN);
122              if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
123                  (e_config->focus_setting == E_FOCUS_NEW_WINDOW))
124                e_border_focus_set(cfd->dia->win->border, 1, 1);
125              return 1;
126           }
127      }
128    return 0;
129 }
130
131 EAPI E_Config_Dialog *
132 e_config_dialog_get(const char *name, const char *class)
133 {
134    Eina_List *l;
135    E_Config_Dialog *cfd;
136
137    EINA_LIST_FOREACH(_e_config_dialog_list, l, cfd)
138      {
139         if (!cfd) continue;
140         if ((!e_util_strcmp(name, cfd->name)) &&
141             (!e_util_strcmp(class, cfd->class)))
142           {
143              return cfd;
144           }
145      }
146    return NULL;
147 }
148
149 /* local subsystem functions */
150 static void
151 _e_config_dialog_free(E_Config_Dialog *cfd)
152 {
153    _e_config_dialog_list = eina_list_remove(_e_config_dialog_list, cfd);
154    if (cfd->auto_apply_timer) _e_config_dialog_cb_auto_apply_timer(cfd);
155    if (cfd->title) eina_stringshare_del(cfd->title);
156    if (cfd->name) eina_stringshare_del(cfd->name);
157    if (cfd->class) eina_stringshare_del(cfd->class);
158    if (cfd->icon) eina_stringshare_del(cfd->icon);
159    if (cfd->cfdata)
160      {
161         cfd->view->free_cfdata(cfd, cfd->cfdata);
162         cfd->cfdata = NULL;
163      }
164    if (cfd->dia)
165      {
166         e_object_del_attach_func_set(E_OBJECT(cfd->dia), NULL);
167         e_object_del(E_OBJECT(cfd->dia));
168         cfd->dia = NULL;
169      }
170    E_FREE(cfd->view);
171    E_FREE(cfd);
172 }
173
174 static void
175 _e_config_dialog_go(E_Config_Dialog *cfd, E_Config_Dialog_CFData_Type type)
176 {
177    Evas *evas;
178    E_Dialog *pdia;
179    Evas_Object *o, *ob, *sf;
180    Evas_Coord mw = 0, mh = 0;
181    char buf[256];
182    void *cfdata;
183
184    pdia = cfd->dia;
185    /* FIXME: get name/class form new call and use here */
186    /* if (type == E_CONFIG_DIALOG_CFDATA_TYPE_BASIC)
187     *   snprintf(buf, sizeof(buf), "%s...%s", cfd->class, "BASIC");
188     * else
189     *   snprintf(buf, sizeof(buf), "%s...%s", cfd->class, "ADVANCED"); */
190    snprintf(buf, sizeof(buf), "_config::%s", cfd->class);
191
192    if (!pdia)  /* creating window for the first time */
193      {
194         if ((cfd->view->normal_win) || (e_config->cfgdlg_normal_wins))
195           cfd->dia = e_dialog_normal_win_new(cfd->con, cfd->name, buf);
196         else
197           cfd->dia = e_dialog_new(cfd->con, cfd->name, buf);
198         e_object_del_attach_func_set(E_OBJECT(cfd->dia),
199                                      _e_config_dialog_cb_dialog_del);
200      } /* window was created before - deleting content only */
201    else if (cfd->dia->content_object)
202      evas_object_del(cfd->dia->content_object);
203
204    cfd->view_type = type;
205    cfd->dia->data = cfd;
206    e_dialog_title_set(cfd->dia, cfd->title);
207    cfdata = cfd->cfdata;
208    if (!cfd->cfdata) cfd->cfdata = cfd->view->create_cfdata(cfd);
209
210    evas = e_win_evas_get(cfd->dia->win);
211    if (type == E_CONFIG_DIALOG_CFDATA_TYPE_BASIC)
212      {
213         if (cfd->view->advanced.create_widgets)
214           {
215              o = e_widget_list_add(evas, 0, 0);
216              ob = cfd->view->basic.create_widgets(cfd, evas, cfd->cfdata);
217              if (cfd->view->scroll)
218                {
219                   e_widget_size_min_resize(ob);
220                   sf = e_widget_scrollframe_simple_add(evas, ob);
221                   e_widget_list_object_append(o, sf, 1, 1, 0.0);
222                }
223              else
224                e_widget_list_object_append(o, ob, 1, 1, 0.0);
225              ob = e_widget_button_add(evas,
226                                       _("Advanced"), "go-next",
227                                       _e_config_dialog_cb_advanced, cfd, NULL);
228              e_widget_list_object_append(o, ob, 0, 0, 1.0);
229           }
230         else
231           {
232              o = cfd->view->basic.create_widgets(cfd, evas, cfd->cfdata);
233              if (cfd->view->scroll)
234                {
235                   e_widget_size_min_resize(o);
236                   o = e_widget_scrollframe_simple_add(evas, o);
237                }
238           }
239      }
240    else
241      {
242         if (cfd->view->basic.create_widgets)
243           {
244              o = e_widget_list_add(evas, 0, 0);
245              ob = cfd->view->advanced.create_widgets(cfd, evas, cfd->cfdata);
246              if (cfd->view->scroll)
247                {
248                   e_widget_size_min_resize(ob);
249                   sf = e_widget_scrollframe_simple_add(evas, ob);
250                   e_widget_list_object_append(o, sf, 1, 1, 0.0);
251                }
252              else
253                e_widget_list_object_append(o, ob, 1, 1, 0.0);
254              ob = e_widget_button_add(evas,
255                                       _("Basic"), "go-next",
256                                       _e_config_dialog_cb_basic, cfd, NULL);
257              e_widget_list_object_append(o, ob, 0, 0, 1.0);
258           }
259         else
260           {
261              o = cfd->view->advanced.create_widgets(cfd, evas, cfd->cfdata);
262              if (cfd->view->scroll)
263                {
264                   e_widget_size_min_resize(o);
265                   o = e_widget_scrollframe_simple_add(evas, o);
266                }
267           }
268      }
269
270    e_widget_size_min_get(o, &mw, &mh);
271    e_widget_on_change_hook_set(o, _e_config_dialog_cb_changed, cfd);
272    e_dialog_content_set(cfd->dia, o, mw, mh);
273
274    if (!pdia) /* dialog window was created in this function call - need to create buttons once */
275      {
276         if (!cfd->hide_buttons)
277           {
278              e_dialog_button_add(cfd->dia, _("OK"), NULL,
279                                  _e_config_dialog_cb_ok, cfd);
280              e_dialog_button_add(cfd->dia, _("Apply"), NULL,
281                                  _e_config_dialog_cb_apply, cfd);
282              if (!cfd->cfg_changed)
283                {
284                   e_dialog_button_disable_num_set(cfd->dia, 0, 1);
285                   e_dialog_button_disable_num_set(cfd->dia, 1, 1);
286                }
287           }
288         e_dialog_button_add(cfd->dia, _("Close"), NULL,
289                             _e_config_dialog_cb_close, cfd);
290      }
291
292    if (cfdata && cfd->cfg_changed_auto)
293      {
294         int changed;
295
296         changed = _e_config_dialog_check_changed(cfd, 0);
297         e_config_dialog_changed_set(cfd, changed);
298      }
299
300    e_dialog_show(cfd->dia);
301    if (cfd->icon) e_dialog_border_icon_set(cfd->dia, cfd->icon);
302 }
303
304 static Eina_Bool
305 _e_config_dialog_cb_auto_apply_timer(void *data)
306 {
307    E_Config_Dialog *cfd;
308
309    cfd = data;
310
311    if (cfd->auto_apply_timer) ecore_timer_del(cfd->auto_apply_timer);
312    cfd->auto_apply_timer = NULL;
313
314    if (cfd->view_type == E_CONFIG_DIALOG_CFDATA_TYPE_BASIC)
315      {
316         if (cfd->view->basic.apply_cfdata)
317           cfd->view->basic.apply_cfdata(cfd, cfd->cfdata);
318      }
319    else
320      {
321         if (cfd->view->advanced.apply_cfdata)
322           cfd->view->advanced.apply_cfdata(cfd, cfd->cfdata);
323      }
324    return ECORE_CALLBACK_CANCEL;
325 }
326
327 static void
328 _e_config_dialog_cb_dialog_del(void *obj)
329 {
330    E_Dialog *dia;
331    E_Config_Dialog *cfd;
332
333    dia = obj;
334    cfd = dia->data;
335    if (cfd->auto_apply_timer) _e_config_dialog_cb_auto_apply_timer(cfd);
336    cfd->dia = NULL;
337    e_object_del(E_OBJECT(cfd));
338 }
339
340 static void
341 _e_config_dialog_cb_ok(void *data __UNUSED__, E_Dialog *dia)
342 {
343    E_Config_Dialog *cfd;
344    int ok = 0;
345
346    cfd = dia->data;
347    if (cfd->view_type == E_CONFIG_DIALOG_CFDATA_TYPE_BASIC)
348      {
349         if (cfd->view->basic.apply_cfdata)
350           ok = cfd->view->basic.apply_cfdata(cfd, cfd->cfdata);
351      }
352    else
353      {
354         if (cfd->view->advanced.apply_cfdata)
355           ok = cfd->view->advanced.apply_cfdata(cfd, cfd->cfdata);
356      }
357    if (ok)
358      e_util_defer_object_del(E_OBJECT(cfd));
359 }
360
361 static void
362 _e_config_dialog_cb_apply(void *data __UNUSED__, E_Dialog *dia)
363 {
364    E_Config_Dialog *cfd;
365    int ok = 0;
366
367    cfd = dia->data;
368    if (cfd->view_type == E_CONFIG_DIALOG_CFDATA_TYPE_BASIC)
369      {
370         if (cfd->view->basic.apply_cfdata)
371           ok = cfd->view->basic.apply_cfdata(cfd, cfd->cfdata);
372      }
373    else
374      {
375         if (cfd->view->advanced.apply_cfdata)
376           ok = cfd->view->advanced.apply_cfdata(cfd, cfd->cfdata);
377      }
378    if ((ok) && (!cfd->hide_buttons))
379      {
380         cfd->cfg_changed = 0;
381         e_dialog_button_disable_num_set(cfd->dia, 0, 1);
382         e_dialog_button_disable_num_set(cfd->dia, 1, 1);
383      }
384 }
385
386 static void
387 _e_config_dialog_cb_advanced(void *data, void *data2 __UNUSED__)
388 {
389    E_Config_Dialog *cfd;
390
391    cfd = data;
392    if (cfd->auto_apply_timer) _e_config_dialog_cb_auto_apply_timer(cfd);
393    _e_config_dialog_go(cfd, E_CONFIG_DIALOG_CFDATA_TYPE_ADVANCED);
394 }
395
396 static void
397 _e_config_dialog_cb_basic(void *data, void *data2 __UNUSED__)
398 {
399    E_Config_Dialog *cfd;
400
401    cfd = data;
402    if (cfd->auto_apply_timer) _e_config_dialog_cb_auto_apply_timer(cfd);
403    _e_config_dialog_go(cfd, E_CONFIG_DIALOG_CFDATA_TYPE_BASIC);
404 }
405
406 static void
407 _e_config_dialog_changed(E_Config_Dialog *cfd)
408 {
409    if (!cfd->hide_buttons)
410      {
411         cfd->cfg_changed = 1;
412         e_dialog_button_disable_num_set(cfd->dia, 0, 0);
413         e_dialog_button_disable_num_set(cfd->dia, 1, 0);
414      }
415    else
416      {
417         if (cfd->auto_apply_timer) ecore_timer_del(cfd->auto_apply_timer);
418         cfd->auto_apply_timer = NULL;
419         cfd->auto_apply_timer =
420           ecore_timer_add(0.5, _e_config_dialog_cb_auto_apply_timer, cfd);
421      }
422 }
423
424 static void
425 _e_config_dialog_unchanged(E_Config_Dialog *cfd)
426 {
427    if (!cfd->hide_buttons)
428      {
429         e_dialog_button_disable_num_set(cfd->dia, 0, 1);
430         e_dialog_button_disable_num_set(cfd->dia, 1, 1);
431      }
432    else
433      {
434         if (cfd->auto_apply_timer)
435           {
436              ecore_timer_del(cfd->auto_apply_timer);
437              cfd->auto_apply_timer = NULL;
438           }
439      }
440 }
441
442 static int
443 _e_config_dialog_check_changed(E_Config_Dialog *cfd, unsigned char def)
444 {
445    int changed = 0;
446
447    if (cfd->view_type == E_CONFIG_DIALOG_CFDATA_TYPE_BASIC)
448      {
449         if (cfd->view->basic.check_changed)
450           changed = cfd->view->basic.check_changed(cfd, cfd->cfdata);
451         else
452           changed = def;
453      }
454    else if (cfd->view_type == E_CONFIG_DIALOG_CFDATA_TYPE_ADVANCED)
455      {
456         if (cfd->view->advanced.check_changed)
457           changed = cfd->view->advanced.check_changed(cfd, cfd->cfdata);
458         else
459           changed = def;
460      }
461
462    return changed;
463 }
464
465 static void
466 _e_config_dialog_cb_changed(void *data, Evas_Object *obj __UNUSED__)
467 {
468    E_Config_Dialog *cfd;
469    int changed;
470
471    cfd = data;
472    if (!cfd->cfg_changed_auto) return;
473    changed = _e_config_dialog_check_changed(cfd, 1);
474
475    e_config_dialog_changed_set(cfd, changed);
476 }
477
478 static void
479 _e_config_dialog_cb_close(void *data __UNUSED__, E_Dialog *dia)
480 {
481    E_Config_Dialog *cfd;
482    int ok = 1;
483
484    cfd = dia->data;
485    if (cfd->auto_apply_timer) _e_config_dialog_cb_auto_apply_timer(cfd);
486    if (cfd->view->close_cfdata)
487      ok = cfd->view->close_cfdata(cfd, cfd->cfdata);
488    if (ok) e_util_defer_object_del(E_OBJECT(cfd));
489 }
490
491 EAPI void
492 e_config_dialog_changed_auto_set(E_Config_Dialog *cfd, unsigned char value)
493 {
494    if (!cfd) return;
495    cfd->cfg_changed_auto = !!value;
496 }
497
498 EAPI void
499 e_config_dialog_changed_set(E_Config_Dialog *cfd, unsigned char value)
500 {
501    if (!cfd) return;
502    cfd->cfg_changed = !!value;
503    if (cfd->cfg_changed)
504      _e_config_dialog_changed(cfd);
505    else
506      _e_config_dialog_unchanged(cfd);
507 }
508