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