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 parent the parent dialog
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 E_API E_Config_Dialog *
e_config_dialog_new(Evas_Object * parent,const char * title,const char * name,const char * class,const char * icon,int icon_size,E_Config_Dialog_View * view,void * data)35 e_config_dialog_new(Evas_Object *parent, 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->parent = parent;
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 E_API int
e_config_dialog_find(const char * name,const char * class)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              E_Client *ec;
108 
109              z = e_zone_current_get();
110              ec = e_win_client_get(cfd->dia->win);
111              e_client_uniconify(ec);
112              elm_win_raise(cfd->dia->win);
113              ec->hidden = 0;
114              e_client_desk_set(ec, e_desk_current_get(z));
115              if (ec->shaded || ec->shading)
116                e_client_unshade(ec, ec->shade_dir);
117              if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
118                  (e_config->focus_setting == E_FOCUS_NEW_WINDOW))
119                evas_object_focus_set(ec->frame, 1);
120              return 1;
121           }
122      }
123    return 0;
124 }
125 
126 E_API E_Config_Dialog *
e_config_dialog_get(const char * name,const char * class)127 e_config_dialog_get(const char *name, const char *class)
128 {
129    Eina_List *l;
130    E_Config_Dialog *cfd;
131 
132    EINA_LIST_FOREACH(_e_config_dialog_list, l, cfd)
133      {
134         if (!cfd) continue;
135         if ((!e_util_strcmp(name, cfd->name)) &&
136             (!e_util_strcmp(class, cfd->class)))
137           {
138              return cfd;
139           }
140      }
141    return NULL;
142 }
143 
144 /* local subsystem functions */
145 static void
_e_config_dialog_free(E_Config_Dialog * cfd)146 _e_config_dialog_free(E_Config_Dialog *cfd)
147 {
148    _e_config_dialog_list = eina_list_remove(_e_config_dialog_list, cfd);
149    if (cfd->auto_apply_timer) _e_config_dialog_cb_auto_apply_timer(cfd);
150    if (cfd->title) eina_stringshare_del(cfd->title);
151    if (cfd->name) eina_stringshare_del(cfd->name);
152    if (cfd->class) eina_stringshare_del(cfd->class);
153    if (cfd->icon) eina_stringshare_del(cfd->icon);
154    if (cfd->view->free_cfdata)
155      {
156         cfd->view->free_cfdata(cfd, cfd->cfdata);
157         cfd->cfdata = NULL;
158      }
159    if (cfd->dia)
160      {
161         e_object_del_attach_func_set(E_OBJECT(cfd->dia), NULL);
162         e_object_del(E_OBJECT(cfd->dia));
163         cfd->dia = NULL;
164      }
165    E_FREE(cfd->view);
166    E_FREE(cfd);
167 }
168 
169 static void
_e_config_dialog_go(E_Config_Dialog * cfd,E_Config_Dialog_CFData_Type type)170 _e_config_dialog_go(E_Config_Dialog *cfd, E_Config_Dialog_CFData_Type type)
171 {
172    Evas *evas;
173    E_Dialog *pdia;
174    Evas_Object *o, *ob, *sf;
175    char buf[256];
176    int mw = -1, mh = -1;
177    void *cfdata;
178 
179    pdia = cfd->dia;
180    /* FIXME: get name/class form new call and use here */
181    /* if (type == E_CONFIG_DIALOG_CFDATA_TYPE_BASIC)
182     *   snprintf(buf, sizeof(buf), "%s...%s", cfd->class, "BASIC");
183     * else
184     *   snprintf(buf, sizeof(buf), "%s...%s", cfd->class, "ADVANCED"); */
185    snprintf(buf, sizeof(buf), "_config::%s", cfd->class);
186 
187    if (!pdia)  /* creating window for the first time */
188      {
189         if ((cfd->view->normal_win) || (e_config->cfgdlg_normal_wins))
190           cfd->dia = e_dialog_normal_win_new(cfd->parent, cfd->name, buf);
191         else
192           cfd->dia = e_dialog_new(cfd->parent, cfd->name, buf);
193         e_object_del_attach_func_set(E_OBJECT(cfd->dia),
194                                      _e_config_dialog_cb_dialog_del);
195      } /* window was created before - deleting content only */
196    else if (cfd->dia->content_object)
197      evas_object_del(cfd->dia->content_object);
198 
199    cfd->view_type = type;
200    cfd->dia->data = cfd;
201    e_dialog_title_set(cfd->dia, cfd->title);
202    cfdata = cfd->cfdata;
203    if (cfd->view->create_cfdata && (!cfd->cfdata))
204      cfd->cfdata = cfd->view->create_cfdata(cfd);
205 
206    evas = evas_object_evas_get(cfd->dia->win);
207    if (type == E_CONFIG_DIALOG_CFDATA_TYPE_BASIC)
208      {
209         if (cfd->view->advanced.create_widgets)
210           {
211              o = e_widget_list_add(evas, 0, 0);
212              ob = cfd->view->basic.create_widgets(cfd, evas, cfd->cfdata);
213              if (cfd->view->scroll)
214                {
215                   e_widget_size_min_resize(ob);
216                   sf = e_widget_scrollframe_simple_add(evas, ob);
217                   e_widget_list_object_append(o, sf, 1, 1, 0.0);
218                }
219              else
220                e_widget_list_object_append(o, ob, 1, 1, 0.0);
221              ob = e_widget_button_add(evas,
222                                       _("Advanced"), "go-next",
223                                       _e_config_dialog_cb_advanced, cfd, NULL);
224              e_widget_list_object_append(o, ob, 0, 0, 1.0);
225           }
226         else
227           {
228              o = cfd->view->basic.create_widgets(cfd, evas, cfd->cfdata);
229              if (cfd->view->scroll)
230                {
231                   e_widget_size_min_resize(o);
232                   o = e_widget_scrollframe_simple_add(evas, o);
233                }
234           }
235      }
236    else
237      {
238         if (cfd->view->basic.create_widgets)
239           {
240              o = e_widget_list_add(evas, 0, 0);
241              ob = cfd->view->advanced.create_widgets(cfd, evas, cfd->cfdata);
242              if (cfd->view->scroll)
243                {
244                   e_widget_size_min_resize(ob);
245                   sf = e_widget_scrollframe_simple_add(evas, ob);
246                   e_widget_list_object_append(o, sf, 1, 1, 0.0);
247                }
248              else
249                e_widget_list_object_append(o, ob, 1, 1, 0.0);
250              ob = e_widget_button_add(evas,
251                                       _("Basic"), "go-next",
252                                       _e_config_dialog_cb_basic, cfd, NULL);
253              e_widget_list_object_append(o, ob, 0, 0, 1.0);
254           }
255         else
256           {
257              o = cfd->view->advanced.create_widgets(cfd, evas, cfd->cfdata);
258              if (cfd->view->scroll)
259                {
260                   e_widget_size_min_resize(o);
261                   o = e_widget_scrollframe_simple_add(evas, o);
262                }
263           }
264      }
265 
266    e_widget_on_change_hook_set(o, _e_config_dialog_cb_changed, cfd);
267    e_widget_size_min_get(o, &mw, &mh);
268    e_dialog_content_set(cfd->dia, o, mw, mh);
269 
270    if (!pdia) /* dialog window was created in this function call - need to create buttons once */
271      {
272         if (!cfd->hide_buttons)
273           {
274              e_dialog_button_add(cfd->dia, _("OK"), NULL,
275                                  _e_config_dialog_cb_ok, cfd);
276              e_dialog_button_add(cfd->dia, _("Apply"), NULL,
277                                  _e_config_dialog_cb_apply, cfd);
278              if (!cfd->cfg_changed)
279                {
280                   e_dialog_button_disable_num_set(cfd->dia, 0, 1);
281                   e_dialog_button_disable_num_set(cfd->dia, 1, 1);
282                }
283           }
284         e_dialog_button_add(cfd->dia, _("Close"), NULL,
285                             _e_config_dialog_cb_close, cfd);
286      }
287 
288    if (cfdata && cfd->cfg_changed_auto)
289      {
290         int changed;
291 
292         changed = _e_config_dialog_check_changed(cfd, 0);
293         e_config_dialog_changed_set(cfd, changed);
294      }
295 
296    e_dialog_show(cfd->dia);
297    if (cfd->icon) e_dialog_border_icon_set(cfd->dia, cfd->icon);
298 }
299 
300 static Eina_Bool
_e_config_dialog_cb_auto_apply_timer(void * data)301 _e_config_dialog_cb_auto_apply_timer(void *data)
302 {
303    E_Config_Dialog *cfd;
304 
305    cfd = data;
306 
307    if (cfd->auto_apply_timer) ecore_timer_del(cfd->auto_apply_timer);
308    cfd->auto_apply_timer = NULL;
309 
310    if (cfd->view_type == E_CONFIG_DIALOG_CFDATA_TYPE_BASIC)
311      {
312         if (cfd->view->basic.apply_cfdata)
313           cfd->view->basic.apply_cfdata(cfd, cfd->cfdata);
314      }
315    else
316      {
317         if (cfd->view->advanced.apply_cfdata)
318           cfd->view->advanced.apply_cfdata(cfd, cfd->cfdata);
319      }
320    return ECORE_CALLBACK_CANCEL;
321 }
322 
323 static void
_e_config_dialog_cb_dialog_del(void * obj)324 _e_config_dialog_cb_dialog_del(void *obj)
325 {
326    E_Dialog *dia;
327    E_Config_Dialog *cfd;
328 
329    dia = obj;
330    cfd = dia->data;
331    if (cfd->auto_apply_timer) _e_config_dialog_cb_auto_apply_timer(cfd);
332    cfd->dia = NULL;
333    e_object_del(E_OBJECT(cfd));
334 }
335 
336 static void
_e_config_dialog_cb_ok(void * data EINA_UNUSED,E_Dialog * dia)337 _e_config_dialog_cb_ok(void *data EINA_UNUSED, E_Dialog *dia)
338 {
339    E_Config_Dialog *cfd;
340    int ok = 0;
341 
342    cfd = dia->data;
343    if (cfd->view_type == E_CONFIG_DIALOG_CFDATA_TYPE_BASIC)
344      {
345         if (cfd->view->basic.apply_cfdata)
346           ok = cfd->view->basic.apply_cfdata(cfd, cfd->cfdata);
347      }
348    else
349      {
350         if (cfd->view->advanced.apply_cfdata)
351           ok = cfd->view->advanced.apply_cfdata(cfd, cfd->cfdata);
352      }
353    if (ok)
354      e_util_defer_object_del(E_OBJECT(cfd));
355 }
356 
357 static void
_e_config_dialog_cb_apply(void * data EINA_UNUSED,E_Dialog * dia)358 _e_config_dialog_cb_apply(void *data EINA_UNUSED, E_Dialog *dia)
359 {
360    E_Config_Dialog *cfd;
361    int ok = 0;
362 
363    cfd = dia->data;
364    if (cfd->view_type == E_CONFIG_DIALOG_CFDATA_TYPE_BASIC)
365      {
366         if (cfd->view->basic.apply_cfdata)
367           ok = cfd->view->basic.apply_cfdata(cfd, cfd->cfdata);
368      }
369    else
370      {
371         if (cfd->view->advanced.apply_cfdata)
372           ok = cfd->view->advanced.apply_cfdata(cfd, cfd->cfdata);
373      }
374    if ((ok) && (!cfd->hide_buttons))
375      {
376         cfd->cfg_changed = 0;
377         e_dialog_button_disable_num_set(cfd->dia, 0, 1);
378         e_dialog_button_disable_num_set(cfd->dia, 1, 1);
379      }
380 }
381 
382 static void
_e_config_dialog_cb_advanced(void * data,void * data2 EINA_UNUSED)383 _e_config_dialog_cb_advanced(void *data, void *data2 EINA_UNUSED)
384 {
385    E_Config_Dialog *cfd;
386 
387    cfd = data;
388    if (cfd->auto_apply_timer) _e_config_dialog_cb_auto_apply_timer(cfd);
389    _e_config_dialog_go(cfd, E_CONFIG_DIALOG_CFDATA_TYPE_ADVANCED);
390 }
391 
392 static void
_e_config_dialog_cb_basic(void * data,void * data2 EINA_UNUSED)393 _e_config_dialog_cb_basic(void *data, void *data2 EINA_UNUSED)
394 {
395    E_Config_Dialog *cfd;
396 
397    cfd = data;
398    if (cfd->auto_apply_timer) _e_config_dialog_cb_auto_apply_timer(cfd);
399    _e_config_dialog_go(cfd, E_CONFIG_DIALOG_CFDATA_TYPE_BASIC);
400 }
401 
402 static void
_e_config_dialog_changed(E_Config_Dialog * cfd)403 _e_config_dialog_changed(E_Config_Dialog *cfd)
404 {
405    if (!cfd->hide_buttons)
406      {
407         cfd->cfg_changed = 1;
408         e_dialog_button_disable_num_set(cfd->dia, 0, 0);
409         e_dialog_button_disable_num_set(cfd->dia, 1, 0);
410      }
411    else
412      {
413         if (cfd->auto_apply_timer) ecore_timer_del(cfd->auto_apply_timer);
414         cfd->auto_apply_timer = NULL;
415         cfd->auto_apply_timer =
416           ecore_timer_loop_add(0.5, _e_config_dialog_cb_auto_apply_timer, cfd);
417      }
418 }
419 
420 static void
_e_config_dialog_unchanged(E_Config_Dialog * cfd)421 _e_config_dialog_unchanged(E_Config_Dialog *cfd)
422 {
423    if (!cfd->hide_buttons)
424      {
425         e_dialog_button_disable_num_set(cfd->dia, 0, 1);
426         e_dialog_button_disable_num_set(cfd->dia, 1, 1);
427      }
428    else
429      {
430         if (cfd->auto_apply_timer)
431           {
432              ecore_timer_del(cfd->auto_apply_timer);
433              cfd->auto_apply_timer = NULL;
434           }
435      }
436 }
437 
438 static int
_e_config_dialog_check_changed(E_Config_Dialog * cfd,unsigned char def)439 _e_config_dialog_check_changed(E_Config_Dialog *cfd, unsigned char def)
440 {
441    int changed = 0;
442 
443    if (cfd->view_type == E_CONFIG_DIALOG_CFDATA_TYPE_BASIC)
444      {
445         if (cfd->view->basic.check_changed)
446           changed = cfd->view->basic.check_changed(cfd, cfd->cfdata);
447         else
448           changed = def;
449      }
450    else if (cfd->view_type == E_CONFIG_DIALOG_CFDATA_TYPE_ADVANCED)
451      {
452         if (cfd->view->advanced.check_changed)
453           changed = cfd->view->advanced.check_changed(cfd, cfd->cfdata);
454         else
455           changed = def;
456      }
457 
458    return changed;
459 }
460 
461 static void
_e_config_dialog_cb_changed(void * data,Evas_Object * obj EINA_UNUSED)462 _e_config_dialog_cb_changed(void *data, Evas_Object *obj EINA_UNUSED)
463 {
464    E_Config_Dialog *cfd;
465    int changed;
466 
467    cfd = data;
468    if (!cfd->cfg_changed_auto) return;
469    changed = _e_config_dialog_check_changed(cfd, 1);
470 
471    e_config_dialog_changed_set(cfd, changed);
472 }
473 
474 static void
_e_config_dialog_cb_close(void * data EINA_UNUSED,E_Dialog * dia)475 _e_config_dialog_cb_close(void *data EINA_UNUSED, E_Dialog *dia)
476 {
477    E_Config_Dialog *cfd;
478    int ok = 1;
479 
480    cfd = dia->data;
481    if (cfd->auto_apply_timer) _e_config_dialog_cb_auto_apply_timer(cfd);
482    if (cfd->view->close_cfdata)
483      ok = cfd->view->close_cfdata(cfd, cfd->cfdata);
484    if (ok) e_util_defer_object_del(E_OBJECT(cfd));
485 }
486 
487 E_API void
e_config_dialog_changed_auto_set(E_Config_Dialog * cfd,unsigned char value)488 e_config_dialog_changed_auto_set(E_Config_Dialog *cfd, unsigned char value)
489 {
490    if (!cfd) return;
491    cfd->cfg_changed_auto = !!value;
492 }
493 
494 E_API void
e_config_dialog_changed_set(E_Config_Dialog * cfd,unsigned char value)495 e_config_dialog_changed_set(E_Config_Dialog *cfd, unsigned char value)
496 {
497    if (!cfd) return;
498    cfd->cfg_changed = !!value;
499    if (cfd->cfg_changed)
500      _e_config_dialog_changed(cfd);
501    else
502      _e_config_dialog_unchanged(cfd);
503 }
504 
505